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-stable-8 mailing list