summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2013-05-03 21:11:57 +0000
committerjhb <jhb@FreeBSD.org>2013-05-03 21:11:57 +0000
commit679fa5ed4e91b1d9e2002d8da43d9c31056fe7a4 (patch)
tree4b4ec8c6d14c8986e2139b96edf75a870d996980 /sys/kern
parent66bb8e0f75e5284e0b64916ea8295efb5ca1fff6 (diff)
downloadFreeBSD-src-679fa5ed4e91b1d9e2002d8da43d9c31056fe7a4.zip
FreeBSD-src-679fa5ed4e91b1d9e2002d8da43d9c31056fe7a4.tar.gz
Similar to 233760 and 236717, export some more useful info about the
kernel-based POSIX semaphore descriptors to userland via procstat(1) and fstat(1): - Change sem file descriptors to track the pathname they are associated with and add a ksem_info() method to copy the path out to a caller-supplied buffer. - Use the fo_stat() method of shared memory objects and ksem_info() to export the path, mode, and value of a semaphore via struct kinfo_file. - Add a struct semstat to the libprocstat(3) interface along with a procstat_get_sem_info() to export the mode and value of a semaphore. - Teach fstat about semaphores and to display their path, mode, and value. MFC after: 2 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_descrip.c31
-rw-r--r--sys/kern/uipc_sem.c19
2 files changed, 49 insertions, 1 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index a9795ca..c0ecf15 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/filio.h>
#include <sys/jail.h>
#include <sys/kernel.h>
+#include <sys/ksem.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -111,6 +112,7 @@ MALLOC_DECLARE(M_FADVISE);
static uma_zone_t file_zone;
+void (*ksem_info)(struct ksem *ks, char *path, size_t size, uint32_t *value);
static int closefp(struct filedesc *fdp, int fd, struct file *fp,
struct thread *td, int holdleaders);
@@ -123,6 +125,7 @@ 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_pts_info(struct tty *tp, struct kinfo_file *kif);
+static int fill_sem_info(struct file *fp, struct kinfo_file *kif);
static int fill_shm_info(struct file *fp, struct kinfo_file *kif);
static int fill_socket_info(struct socket *so, struct kinfo_file *kif);
static int fill_vnode_info(struct vnode *vp, struct kinfo_file *kif);
@@ -2968,6 +2971,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
struct shmfd *shmfd;
struct socket *so;
struct vnode *vp;
+ struct ksem *ks;
struct file *fp;
struct proc *p;
struct tty *tp;
@@ -2996,6 +3000,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
continue;
bzero(kif, sizeof(*kif));
kif->kf_structsize = sizeof(*kif);
+ ks = NULL;
vp = NULL;
so = NULL;
tp = NULL;
@@ -3041,6 +3046,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
case DTYPE_SEM:
kif->kf_type = KF_TYPE_SEM;
+ ks = fp->f_data;
break;
case DTYPE_PTS:
@@ -3150,6 +3156,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
}
if (shmfd != NULL)
shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
+ if (ks != NULL && ksem_info != NULL)
+ ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL);
error = SYSCTL_OUT(req, kif, sizeof(*kif));
if (error)
break;
@@ -3220,6 +3228,9 @@ export_fd_to_sb(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_SEM:
+ error = fill_sem_info((struct file *)data, kif);
+ break;
case KF_TYPE_SHM:
error = fill_shm_info((struct file *)data, kif);
break;
@@ -3387,6 +3398,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
case DTYPE_SEM:
type = KF_TYPE_SEM;
+ data = fp;
break;
case DTYPE_PTS:
@@ -3621,6 +3633,25 @@ fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif)
}
static int
+fill_sem_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);
+ if (ksem_info == NULL)
+ return (1);
+ ksem_info(fp->f_data, kif->kf_path, sizeof(kif->kf_path),
+ &kif->kf_un.kf_sem.kf_sem_value);
+ kif->kf_un.kf_sem.kf_sem_mode = sb.st_mode;
+ return (0);
+}
+
+static int
fill_shm_info(struct file *fp, struct kinfo_file *kif)
{
struct thread *td;
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index 509f32e..a9f60f1 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -71,7 +71,6 @@ FEATURE(p1003_1b_semaphores, "POSIX P1003.1B semaphores support");
* TODO
*
* - Resource limits?
- * - Update fstat(1)
* - Replace global sem_lock with mtx_pool locks?
* - Add a MAC check_create() hook for creating new named semaphores.
*/
@@ -407,6 +406,7 @@ ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks)
map->km_path = path;
map->km_fnv = fnv;
map->km_ksem = ksem_hold(ks);
+ ks->ks_path = path;
LIST_INSERT_HEAD(KSEM_HASH(fnv), map, km_link);
}
@@ -428,6 +428,7 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
error = ksem_access(map->km_ksem, ucred);
if (error)
return (error);
+ map->km_ksem->ks_path = NULL;
LIST_REMOVE(map, km_link);
ksem_drop(map->km_ksem);
free(map->km_path, M_KSEM);
@@ -439,6 +440,20 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
return (ENOENT);
}
+static void
+ksem_info_impl(struct ksem *ks, char *path, size_t size, uint32_t *value)
+{
+
+ if (ks->ks_path == NULL)
+ return;
+ sx_slock(&ksem_dict_lock);
+ if (ks->ks_path != NULL)
+ strlcpy(path, ks->ks_path, size);
+ if (value != NULL)
+ *value = ks->ks_value;
+ sx_sunlock(&ksem_dict_lock);
+}
+
static int
ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
int compat32)
@@ -1014,6 +1029,7 @@ ksem_module_init(void)
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 200112L);
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
+ ksem_info = ksem_info_impl;
error = syscall_helper_register(ksem_syscalls);
if (error)
@@ -1035,6 +1051,7 @@ ksem_module_destroy(void)
#endif
syscall_helper_unregister(ksem_syscalls);
+ ksem_info = NULL;
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 0);
hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
sx_destroy(&ksem_dict_lock);
OpenPOWER on IntegriCloud