svn commit: r252164 - in stable/8: sys/kern sys/sys usr.bin/fstat
John Baldwin
jhb at FreeBSD.org
Mon Jun 24 17:09:30 UTC 2013
Author: jhb
Date: Mon Jun 24 17:09:28 2013
New Revision: 252164
URL: http://svnweb.freebsd.org/changeset/base/252164
Log:
MFC 250223:
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 ksem_info() to export the path of a semaphore via struct kinfo_file.
- Teach fstat about semaphores and to display their path, mode, and value.
Modified:
stable/8/sys/kern/kern_descrip.c
stable/8/sys/kern/uipc_sem.c
stable/8/sys/sys/ksem.h
stable/8/usr.bin/fstat/fstat.1
stable/8/usr.bin/fstat/fstat.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/kern/ (props changed)
stable/8/sys/sys/ (props changed)
stable/8/usr.bin/fstat/ (props changed)
Modified: stable/8/sys/kern/kern_descrip.c
==============================================================================
--- stable/8/sys/kern/kern_descrip.c Mon Jun 24 16:04:59 2013 (r252163)
+++ stable/8/sys/kern/kern_descrip.c Mon Jun 24 17:09:28 2013 (r252164)
@@ -52,6 +52,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>
@@ -96,6 +97,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);
/* Flags for do_dup() */
#define DUP_FIXED 0x1 /* Force fixed allocation */
@@ -2764,6 +2766,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
struct shmfd *shmfd;
struct socket *so;
struct vnode *vp;
+ struct ksem *ks;
struct file *fp;
struct proc *p;
struct tty *tp;
@@ -2796,6 +2799,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
continue;
bzero(kif, sizeof(*kif));
kif->kf_structsize = sizeof(*kif);
+ ks = NULL;
vp = NULL;
so = NULL;
tp = NULL;
@@ -2840,6 +2844,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
case DTYPE_SEM:
kif->kf_type = KF_TYPE_SEM;
+ ks = fp->f_data;
break;
case DTYPE_PTS:
@@ -2945,6 +2950,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
}
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;
@@ -3022,6 +3029,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
struct shmfd *shmfd;
struct socket *so;
struct vnode *vp;
+ struct ksem *ks;
struct file *fp;
struct proc *p;
struct tty *tp;
@@ -3054,6 +3062,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
if ((fp = fdp->fd_ofiles[i]) == NULL)
continue;
bzero(kif, sizeof(*kif));
+ ks = NULL;
vp = NULL;
so = NULL;
tp = NULL;
@@ -3098,6 +3107,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
case DTYPE_SEM:
kif->kf_type = KF_TYPE_SEM;
+ ks = fp->f_data;
break;
case DTYPE_PTS:
@@ -3203,6 +3213,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
}
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);
/* Pack record size down */
kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
strlen(kif->kf_path) + 1;
Modified: stable/8/sys/kern/uipc_sem.c
==============================================================================
--- stable/8/sys/kern/uipc_sem.c Mon Jun 24 16:04:59 2013 (r252163)
+++ stable/8/sys/kern/uipc_sem.c Mon Jun 24 17:09:28 2013 (r252164)
@@ -344,6 +344,7 @@ ksem_insert(char *path, Fnv32_t fnv, str
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);
}
@@ -365,6 +366,7 @@ ksem_remove(char *path, Fnv32_t fnv, str
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);
@@ -376,6 +378,20 @@ ksem_remove(char *path, Fnv32_t fnv, str
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)
@@ -953,6 +969,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)
@@ -974,6 +991,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);
Modified: stable/8/sys/sys/ksem.h
==============================================================================
--- stable/8/sys/sys/ksem.h Mon Jun 24 16:04:59 2013 (r252163)
+++ stable/8/sys/sys/ksem.h Mon Jun 24 17:09:28 2013 (r252164)
@@ -29,7 +29,7 @@
#ifndef _POSIX4_KSEM_H_
#define _POSIX4_KSEM_H_
-#ifndef _KERNEL
+#if !defined(_KERNEL) && !defined(_WANT_FILE)
#error "no user-servicable parts inside"
#endif
@@ -57,9 +57,15 @@ struct ksem {
struct timespec ks_birthtime;
struct label *ks_label; /* MAC label */
+ const char *ks_path;
};
#define KS_ANONYMOUS 0x0001 /* Anonymous (unnamed) semaphore. */
#define KS_DEAD 0x0002 /* No new waiters allowed. */
+#ifdef _KERNEL
+extern void (*ksem_info)(struct ksem *ks, char *path, size_t size,
+ uint32_t *value);
+#endif
+
#endif /* !_POSIX4_KSEM_H_ */
Modified: stable/8/usr.bin/fstat/fstat.1
==============================================================================
--- stable/8/usr.bin/fstat/fstat.1 Mon Jun 24 16:04:59 2013 (r252163)
+++ stable/8/usr.bin/fstat/fstat.1 Mon Jun 24 17:09:28 2013 (r252164)
@@ -159,6 +159,8 @@ using a symbolic format (see
otherwise, the mode is printed
as an octal number.
.It Li SZ\&|DV
+If the file is a semaphore,
+prints the current value of the semaphore.
If the file is not a character or block special, prints the size of
the file in bytes.
Otherwise, if the
Modified: stable/8/usr.bin/fstat/fstat.c
==============================================================================
--- stable/8/usr.bin/fstat/fstat.c Mon Jun 24 16:04:59 2013 (r252163)
+++ stable/8/usr.bin/fstat/fstat.c Mon Jun 24 17:09:28 2013 (r252164)
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#define _WANT_FILE
#include <sys/file.h>
#include <sys/conf.h>
+#include <sys/ksem.h>
#include <sys/mman.h>
#define _KERNEL
#include <sys/pipe.h>
@@ -156,6 +157,7 @@ char *getmnton(struct mount *m);
void pipetrans(struct pipe *pi, int i, int flag);
void socktrans(struct socket *sock, int i);
void ptstrans(struct tty *tp, int i, int flag);
+void semtrans(struct ksem *ksemp, int i, int flag);
void shmtrans(struct shmfd *shmp, int i, int flag);
void getinetproto(int number);
int getfname(const char *filename);
@@ -426,6 +428,12 @@ dofiles(struct kinfo_proc *kp)
shmtrans(file.f_data, i, file.f_flag);
}
#endif
+#ifdef DTYPE_SEM
+ else if (file.f_type == DTYPE_SEM) {
+ if (checkfile == 0)
+ semtrans(file.f_data, i, file.f_flag);
+ }
+#endif
else {
dprintf(stderr,
"unknown file type %d for file %d of pid %d\n",
@@ -948,6 +956,55 @@ bad:
}
void
+semtrans(struct ksem *ksemp, int i, int flag)
+{
+ struct ksem ks;
+ char name[MAXPATHLEN];
+ char mode[15];
+ char rw[3];
+ unsigned j;
+
+ PREFIX(i);
+
+ if (!KVM_READ(ksemp, &ks, sizeof(struct ksem))) {
+ dprintf(stderr, "can't read sem at %p\n", ksemp);
+ goto bad;
+ }
+
+ if (ks.ks_path != NULL) {
+ for (j = 0; j < sizeof(name) - 1; j++) {
+ if (!KVM_READ(ks.ks_path + j, name + j, 1))
+ break;
+ if (name[j] == '\0')
+ break;
+ }
+ name[j] = '\0';
+ } else
+ name[0] = '\0';
+
+ rw[0] = '\0';
+ if (flag & FREAD)
+ strcat(rw, "r");
+ if (flag & FWRITE)
+ strcat(rw, "w");
+
+ ks.ks_mode |= S_IFREG;
+ if (nflg) {
+ printf(" ");
+ (void)snprintf(mode, sizeof(mode), "%o", ks.ks_mode);
+ } else {
+ printf(" %-15s", name[0] != '\0' ? name : "-");
+ strmode(ks.ks_mode, mode);
+ }
+ printf(" %10s %6u", mode, ks.ks_value);
+ printf(" %2s\n", rw);
+
+ return;
+bad:
+ printf("* error\n");
+}
+
+void
shmtrans(struct shmfd *shmp, int i, int flag)
{
struct shmfd shm;
More information about the svn-src-all
mailing list