summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-04-01 18:22:48 +0000
committerjhb <jhb@FreeBSD.org>2012-04-01 18:22:48 +0000
commit506e2f15b93a1584a9103782c48037c858a30609 (patch)
treec2db61e497320454ff8abdab4b6faede73162985 /lib
parentd5bc632dfb8beb870403790342bc3e9573c4f038 (diff)
downloadFreeBSD-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 'lib')
-rw-r--r--lib/libprocstat/Symbol.map4
-rw-r--r--lib/libprocstat/Versions.def5
-rw-r--r--lib/libprocstat/libprocstat.315
-rw-r--r--lib/libprocstat/libprocstat.c72
-rw-r--r--lib/libprocstat/libprocstat.h6
5 files changed, 101 insertions, 1 deletions
diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map
index b5d64d0..0509066 100644
--- a/lib/libprocstat/Symbol.map
+++ b/lib/libprocstat/Symbol.map
@@ -14,3 +14,7 @@ FBSD_1.2 {
procstat_open_kvm;
procstat_open_sysctl;
};
+
+FBSD_1.3 {
+ procstat_get_shm_info;
+};
diff --git a/lib/libprocstat/Versions.def b/lib/libprocstat/Versions.def
index d69f5c9..ed958db 100644
--- a/lib/libprocstat/Versions.def
+++ b/lib/libprocstat/Versions.def
@@ -3,3 +3,8 @@
# This version was first added to 9.0-current.
FBSD_1.2 {
};
+
+# This version was first added to 10.0-current.
+FBSD_1.3 {
+} FBSD_1.2;
+
diff --git a/lib/libprocstat/libprocstat.3 b/lib/libprocstat/libprocstat.3
index 49799f5..07fffb2 100644
--- a/lib/libprocstat/libprocstat.3
+++ b/lib/libprocstat/libprocstat.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 12, 2011
+.Dd April 1, 2012
.Dt LIBPROCSTAT 3
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Nm procstat_freeprocs ,
.Nm procstat_get_pipe_info ,
.Nm procstat_get_pts_info ,
+.Nm procstat_get_shm_info ,
.Nm procstat_get_socket_info ,
.Nm procstat_get_vnode_info
.Nd library interface for file and process information retrieval
@@ -70,6 +71,13 @@
.Fa "char *errbuf"
.Fc
.Ft int
+.Fo procstat_get_shm_info
+.Fa "struct procstat *procstat"
+.Fa "struct filestat *fst"
+.Fa "struct shmstat *shm"
+.Fa "char *errbuf"
+.Fc
+.Ft int
.Fo procstat_get_socket_info
.Fa "struct procstat *procstat"
.Fa "struct filestat *fst"
@@ -191,10 +199,12 @@ function call.
The
.Fn procstat_get_pipe_info ,
.Fn procstat_get_pts_info ,
+.Fn procstat_get_shm_info ,
.Fn procstat_get_socket_info
and
.Fn procstat_get_vnode_info
functions are used to retrive information about pipes, pseudo-terminals,
+shared memory objects,
sockets, and vnodes, respectively.
Each of them have a similar interface API.
The
@@ -231,11 +241,14 @@ argument indicates an actual error message in case of failure.
.Nm procstat_get_pipe_info
.It Li PS_FST_TYPE_PTS
.Nm procstat_get_pts_info
+.It Li PS_FST_TYPE_SHM
+.Nm procstat_get_shm_info
.El
.Sh SEE ALSO
.Xr fstat 1 ,
.Xr fuser 1 ,
.Xr pipe 2 ,
+.Xr shm_open 2 ,
.Xr socket 2 ,
.Xr kvm 3 ,
.Xr queue 3 ,
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 <sys/file.h>
#include <sys/conf.h>
+#include <sys/mman.h>
#define _KERNEL
#include <sys/mount.h>
#include <sys/pipe.h>
@@ -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)
{
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index f1ca109..c00a179 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -123,6 +123,10 @@ struct pipestat {
uint64_t addr;
uint64_t peer;
};
+struct shmstat {
+ uint64_t size;
+ uint16_t mode;
+};
struct sockstat {
uint64_t inp_ppcb;
uint64_t so_addr;
@@ -152,6 +156,8 @@ int procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst,
struct pipestat *pipe, char *errbuf);
int procstat_get_pts_info(struct procstat *procstat, struct filestat *fst,
struct ptsstat *pts, char *errbuf);
+int procstat_get_shm_info(struct procstat *procstat, struct filestat *fst,
+ struct shmstat *shm, char *errbuf);
int procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
struct sockstat *sock, char *errbuf);
int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst,
OpenPOWER on IntegriCloud