diff options
author | jhb <jhb@FreeBSD.org> | 2012-04-01 18:22:48 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-04-01 18:22:48 +0000 |
commit | 506e2f15b93a1584a9103782c48037c858a30609 (patch) | |
tree | c2db61e497320454ff8abdab4b6faede73162985 /sys/kern | |
parent | d5bc632dfb8beb870403790342bc3e9573c4f038 (diff) | |
download | FreeBSD-src-506e2f15b93a1584a9103782c48037c858a30609.zip FreeBSD-src-506e2f15b93a1584a9103782c48037c858a30609.tar.gz |
Export some more useful info about shared memory objects to userland
via procstat(1) and fstat(1):
- Change shm file descriptors to track the pathname they are associated
with and add a shm_path() method to copy the path out to a caller-supplied
buffer.
- Use the fo_stat() method of shared memory objects and shm_path() to
export the path, mode, and size of a shared memory object via
struct kinfo_file.
- Add a struct shmstat to the libprocstat(3) interface along with a
procstat_get_shm_info() to export the mode and size of a shared memory
object.
- Change procstat to always print out the path for a given object if it
is valid.
- Teach fstat about shared memory objects and to display their path,
mode, and size.
MFC after: 2 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_descrip.c | 28 | ||||
-rw-r--r-- | sys/kern/uipc_shm.c | 14 |
2 files changed, 42 insertions, 0 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 18fd937..251a558 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #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> @@ -126,6 +127,7 @@ static int fill_pts_info(struct tty *tp, struct kinfo_file *kif); 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_shm_info(struct file *fp, struct kinfo_file *kif); /* * A process is initially started out with NDFILE descriptors stored within @@ -2958,6 +2960,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) struct kinfo_ofile *kif; struct filedesc *fdp; int error, i, *name; + struct shmfd *shmfd; struct socket *so; struct vnode *vp; struct file *fp; @@ -2995,6 +2998,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) vp = NULL; so = NULL; tp = NULL; + shmfd = NULL; kif->kf_fd = i; #ifdef CAPABILITIES @@ -3046,6 +3050,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) case DTYPE_SHM: kif->kf_type = KF_TYPE_SHM; + shmfd = fp->f_data; break; case DTYPE_SEM: @@ -3159,6 +3164,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS) strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path)); } + if (shmfd != NULL) + shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path)); error = SYSCTL_OUT(req, kif, sizeof(*kif)); if (error) break; @@ -3229,6 +3236,9 @@ export_fd_for_sysctl(void *data, int type, int fd, int fflags, int refcnt, case KF_TYPE_PROCDESC: error = fill_procdesc_info((struct procdesc *)data, kif); break; + case KF_TYPE_SHM: + error = fill_shm_info((struct file *)data, kif); + break; default: error = 0; } @@ -3398,6 +3408,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) case DTYPE_SHM: type = KF_TYPE_SHM; + data = fp; break; case DTYPE_SEM: @@ -3621,6 +3632,23 @@ fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif) 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, sysctl_kern_proc_filedesc, "Process filedesc entries"); diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index ce7c722..7f75bdc 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -468,6 +468,7 @@ shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd) map->sm_path = path; map->sm_fnv = fnv; map->sm_shmfd = shm_hold(shmfd); + shmfd->shm_path = path; LIST_INSERT_HEAD(SHM_HASH(fnv), map, sm_link); } @@ -490,6 +491,7 @@ shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred) FREAD | FWRITE); if (error) return (error); + map->sm_shmfd->shm_path = NULL; LIST_REMOVE(map, sm_link); shm_drop(map->sm_shmfd); free(map->sm_path, M_SHMFD); @@ -844,3 +846,15 @@ shm_unmap(struct file *fp, void *mem, size_t size) VM_OBJECT_UNLOCK(obj); return (0); } + +void +shm_path(struct shmfd *shmfd, char *path, size_t size) +{ + + 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); +} |