Add support for displaying a process' current working directory, root
directory, and jail directory within procstat. While this functionality is available already in fstat, encapsulating it in the kern.proc.filedesc sysctl makes it accessible without using kvm and thus without needing elevated permissions. The new procstat output looks like: PID COMM FD T V FLAGS REF OFFSET PRO NAME 76792 tcsh cwd v d -------- - - - /usr/src 76792 tcsh root v d -------- - - - / 76792 tcsh 15 v c rw------ 16 9130 - - 76792 tcsh 16 v c rw------ 16 9130 - - 76792 tcsh 17 v c rw------ 16 9130 - - 76792 tcsh 18 v c rw------ 16 9130 - - 76792 tcsh 19 v c rw------ 16 9130 - - I am also bumping __FreeBSD_version for this as this new feature will be used in at least one port. Reviewed by: rwatson Approved by: rwatson
This commit is contained in:
parent
7445f79ec2
commit
7e24637c24
@ -2446,6 +2446,47 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
|
||||
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
|
||||
0, 0, sysctl_kern_file, "S,xfile", "Entire file table");
|
||||
|
||||
static int
|
||||
export_vnode_for_sysctl(struct vnode *vp, int type,
|
||||
struct kinfo_file *kif, struct filedesc *fdp, struct sysctl_req *req)
|
||||
{
|
||||
int error;
|
||||
char *fullpath, *freepath;
|
||||
int vfslocked;
|
||||
|
||||
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. */
|
||||
KASSERT(vp->v_type == VDIR, ("export_vnode_for_sysctl: vnode not directory"));
|
||||
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);
|
||||
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
vn_fullpath(curthread, vp, &fullpath, &freepath);
|
||||
vput(vp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
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.
|
||||
*/
|
||||
@ -2473,6 +2514,15 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS)
|
||||
PROC_UNLOCK(p);
|
||||
kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
if (fdp->fd_cdir != NULL)
|
||||
export_vnode_for_sysctl(fdp->fd_cdir, KF_FD_TYPE_CWD, kif,
|
||||
fdp, req);
|
||||
if (fdp->fd_rdir != NULL)
|
||||
export_vnode_for_sysctl(fdp->fd_rdir, KF_FD_TYPE_ROOT, kif,
|
||||
fdp, req);
|
||||
if (fdp->fd_jdir != NULL)
|
||||
export_vnode_for_sysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
|
||||
fdp, req);
|
||||
for (i = 0; i < fdp->fd_nfiles; i++) {
|
||||
if ((fp = fdp->fd_ofiles[i]) == NULL)
|
||||
continue;
|
||||
|
@ -57,7 +57,7 @@
|
||||
* is created, otherwise 1.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 800018 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 800019 /* Master, propagated to newvers */
|
||||
|
||||
#ifndef LOCORE
|
||||
#include <sys/types.h>
|
||||
|
@ -234,7 +234,7 @@ struct user {
|
||||
};
|
||||
|
||||
/*
|
||||
* The KERN_PROC_FILE sysctl allows a process to dumpt the file descriptor
|
||||
* The KERN_PROC_FILE sysctl allows a process to dump the file descriptor
|
||||
* array of another process.
|
||||
*/
|
||||
#define KF_TYPE_NONE 0
|
||||
@ -259,6 +259,10 @@ struct user {
|
||||
#define KF_VTYPE_VBAD 8
|
||||
#define KF_VTYPE_UNKNOWN 255
|
||||
|
||||
#define KF_FD_TYPE_CWD -1 /* Current working directory */
|
||||
#define KF_FD_TYPE_ROOT -2 /* Root directory */
|
||||
#define KF_FD_TYPE_JAIL -3 /* Jail directory */
|
||||
|
||||
#define KF_FLAG_READ 0x00000001
|
||||
#define KF_FLAG_WRITE 0x00000002
|
||||
#define KF_FLAG_APPEND 0x00000004
|
||||
|
@ -140,7 +140,7 @@ procstat_files(pid_t pid, struct kinfo_proc *kipp)
|
||||
size_t len;
|
||||
|
||||
if (!hflag)
|
||||
printf("%5s %-16s %3s %1s %1s %-8s %3s %7s %-3s %-12s\n",
|
||||
printf("%5s %-16s %4s %1s %1s %-8s %3s %7s %-3s %-12s\n",
|
||||
"PID", "COMM", "FD", "T", "V", "FLAGS", "REF", "OFFSET",
|
||||
"PRO", "NAME");
|
||||
|
||||
@ -172,7 +172,23 @@ procstat_files(pid_t pid, struct kinfo_proc *kipp)
|
||||
errx(-1, "kinfo_file mismatch");
|
||||
printf("%5d ", pid);
|
||||
printf("%-16s ", kipp->ki_comm);
|
||||
printf("%3d ", kif->kf_fd);
|
||||
switch (kif->kf_fd) {
|
||||
case KF_FD_TYPE_CWD:
|
||||
printf(" cwd ");
|
||||
break;
|
||||
|
||||
case KF_FD_TYPE_ROOT:
|
||||
printf("root ");
|
||||
break;
|
||||
|
||||
case KF_FD_TYPE_JAIL:
|
||||
printf("jail ");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%4d ", kif->kf_fd);
|
||||
break;
|
||||
}
|
||||
switch (kif->kf_type) {
|
||||
case KF_TYPE_VNODE:
|
||||
str = "v";
|
||||
@ -264,8 +280,14 @@ procstat_files(pid_t pid, struct kinfo_proc *kipp)
|
||||
printf("%s", kif->kf_flags & KF_FLAG_NONBLOCK ? "n" : "-");
|
||||
printf("%s", kif->kf_flags & KF_FLAG_DIRECT ? "d" : "-");
|
||||
printf("%s ", kif->kf_flags & KF_FLAG_HASLOCK ? "l" : "-");
|
||||
if (kif->kf_ref_count > -1)
|
||||
printf("%3d ", kif->kf_ref_count);
|
||||
else
|
||||
printf("%3c ", '-');
|
||||
if (kif->kf_offset > -1)
|
||||
printf("%7jd ", (intmax_t)kif->kf_offset);
|
||||
else
|
||||
printf("%7c ", '-');
|
||||
|
||||
switch (kif->kf_type) {
|
||||
case KF_TYPE_VNODE:
|
||||
|
Loading…
Reference in New Issue
Block a user