From 506e2f15b93a1584a9103782c48037c858a30609 Mon Sep 17 00:00:00 2001 From: jhb Date: Sun, 1 Apr 2012 18:22:48 +0000 Subject: 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 --- lib/libprocstat/libprocstat.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'lib/libprocstat/libprocstat.c') diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index facce11..167d91a 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #define _WANT_FILE #include #include +#include #define _KERNEL #include #include @@ -114,6 +115,10 @@ static int procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, char *errbuf); static int procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, struct ptsstat *pts, char *errbuf); +static int procstat_get_shm_info_sysctl(struct filestat *fst, + struct shmstat *shm, char *errbuf); +static int procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, + struct shmstat *shm, char *errbuf); static int procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock, char *errbuf); static int procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst, @@ -469,6 +474,10 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap data = file.f_data; break; #endif + case DTYPE_SHM: + type = PS_FST_TYPE_SHM; + data = file.f_data; + break; default: continue; } @@ -849,6 +858,69 @@ procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, } int +procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, + struct shmstat *shm, char *errbuf) +{ + + assert(shm); + if (procstat->type == PROCSTAT_KVM) { + return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, + errbuf)); + } else if (procstat->type == PROCSTAT_SYSCTL) { + return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); + } else { + warnx("unknown access method: %d", procstat->type); + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); + } +} + +static int +procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, + struct shmstat *shm, char *errbuf) +{ + struct shmfd shmfd; + void *shmfdp; + + assert(kd); + assert(shm); + assert(fst); + bzero(shm, sizeof(*shm)); + shmfdp = fst->fs_typedep; + if (shmfdp == NULL) + goto fail; + if (!kvm_read_all(kd, (unsigned long)shmfdp, &shmfd, + sizeof(struct shmfd))) { + warnx("can't read shmfd at %p", (void *)shmfdp); + goto fail; + } + shm->mode = S_IFREG | shmfd.shm_mode; + shm->size = shmfd.shm_size; + return (0); + +fail: + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); +} + +static int +procstat_get_shm_info_sysctl(struct filestat *fst, struct shmstat *shm, + char *errbuf __unused) +{ + struct kinfo_file *kif; + + assert(shm); + assert(fst); + bzero(shm, sizeof(*shm)); + kif = fst->fs_typedep; + if (kif == NULL) + return (0); + shm->size = kif->kf_un.kf_file.kf_file_size; + shm->mode = kif->kf_un.kf_file.kf_file_mode; + return (0); +} + +int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, struct vnstat *vn, char *errbuf) { -- cgit v1.1