Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Jun 2012 21:57:03 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r236699 - in stable/8: sys/kern sys/sys usr.bin/fstat usr.bin/procstat
Message-ID:  <201206062157.q56Lv3a5040780@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Jun  6 21:57:03 2012
New Revision: 236699
URL: http://svn.freebsd.org/changeset/base/236699

Log:
  MFC 233760:
  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 shm_path() to export the path of a shared memory object via
    struct kinfo_file.
  - 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.

Modified:
  stable/8/sys/kern/kern_descrip.c
  stable/8/sys/kern/uipc_shm.c
  stable/8/sys/sys/mman.h
  stable/8/usr.bin/fstat/fstat.c
  stable/8/usr.bin/procstat/procstat_files.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/usr.bin/fstat/   (props changed)
  stable/8/usr.bin/procstat/   (props changed)

Modified: stable/8/sys/kern/kern_descrip.c
==============================================================================
--- stable/8/sys/kern/kern_descrip.c	Wed Jun  6 21:49:31 2012	(r236698)
+++ stable/8/sys/kern/kern_descrip.c	Wed Jun  6 21:57:03 2012	(r236699)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/mqueue.h>
 #include <sys/mutex.h>
@@ -2742,6 +2743,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
 	struct kinfo_ofile *kif;
 	struct filedesc *fdp;
 	int error, i, *name;
+	struct shmfd *shmfd;
 	struct socket *so;
 	struct vnode *vp;
 	struct file *fp;
@@ -2779,6 +2781,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
 		vp = NULL;
 		so = NULL;
 		tp = NULL;
+		shmfd = NULL;
 		kif->kf_fd = i;
 		switch (fp->f_type) {
 		case DTYPE_VNODE:
@@ -2814,6 +2817,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
 
 		case DTYPE_SHM:
 			kif->kf_type = KF_TYPE_SHM;
+			shmfd = fp->f_data;
 			break;
 
 		case DTYPE_SEM:
@@ -2921,6 +2925,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
 			strlcpy(kif->kf_path, tty_devname(tp),
 			    sizeof(kif->kf_path));
 		}
+		if (shmfd != NULL)
+			shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
 		error = SYSCTL_OUT(req, kif, sizeof(*kif));
 		if (error)
 			break;
@@ -2995,6 +3001,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 	struct kinfo_file *kif;
 	struct filedesc *fdp;
 	int error, i, *name;
+	struct shmfd *shmfd;
 	struct socket *so;
 	struct vnode *vp;
 	struct file *fp;
@@ -3032,6 +3039,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 		vp = NULL;
 		so = NULL;
 		tp = NULL;
+		shmfd = NULL;
 		kif->kf_fd = i;
 		switch (fp->f_type) {
 		case DTYPE_VNODE:
@@ -3067,6 +3075,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 
 		case DTYPE_SHM:
 			kif->kf_type = KF_TYPE_SHM;
+			shmfd = fp->f_data;
 			break;
 
 		case DTYPE_SEM:
@@ -3174,6 +3183,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 			strlcpy(kif->kf_path, tty_devname(tp),
 			    sizeof(kif->kf_path));
 		}
+		if (shmfd != NULL)
+			shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
 		/* Pack record size down */
 		kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
 		    strlen(kif->kf_path) + 1;

Modified: stable/8/sys/kern/uipc_shm.c
==============================================================================
--- stable/8/sys/kern/uipc_shm.c	Wed Jun  6 21:49:31 2012	(r236698)
+++ stable/8/sys/kern/uipc_shm.c	Wed Jun  6 21:57:03 2012	(r236699)
@@ -453,6 +453,7 @@ shm_insert(char *path, Fnv32_t fnv, stru
 	map->sm_path = path;
 	map->sm_fnv = fnv;
 	map->sm_shmfd = shm_hold(shmfd);
+	shmfd->shm_path = path;
 	LIST_INSERT_HEAD(SHM_HASH(fnv), map, sm_link);
 }
 
@@ -475,6 +476,7 @@ shm_remove(char *path, Fnv32_t fnv, stru
 			    FREAD | FWRITE);
 			if (error)
 				return (error);
+			map->sm_shmfd->shm_path = NULL;
 			LIST_REMOVE(map, sm_link);
 			shm_drop(map->sm_shmfd);
 			free(map->sm_path, M_SHMFD);
@@ -754,3 +756,15 @@ shm_unmap(struct file *fp, void *mem, si
 	VM_OBJECT_UNLOCK(obj);
 	return (0);
 }
+
+void
+shm_path(struct shmfd *shmfd, char *path, size_t size)
+{
+
+	if (shmfd->shm_path == NULL)
+		return;
+	sx_slock(&shm_dict_lock);
+	if (shmfd->shm_path != NULL)
+		strlcpy(path, shmfd->shm_path, size);
+	sx_sunlock(&shm_dict_lock);
+}

Modified: stable/8/sys/sys/mman.h
==============================================================================
--- stable/8/sys/sys/mman.h	Wed Jun  6 21:49:31 2012	(r236698)
+++ stable/8/sys/sys/mman.h	Wed Jun  6 21:57:03 2012	(r236699)
@@ -178,7 +178,7 @@ typedef	__size_t	size_t;
 #define	_SIZE_T_DECLARED
 #endif
 
-#ifdef _KERNEL
+#if defined(_KERNEL) || defined(_WANT_FILE)
 #include <vm/vm.h>
 
 struct file;
@@ -202,12 +202,16 @@ struct shmfd {
 	struct timespec	shm_birthtime;
 
 	struct label	*shm_label;		/* MAC label */
+	const char	*shm_path;
 };
+#endif
 
+#ifdef _KERNEL
 int	shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
 	    vm_object_t *obj);
 int	shm_map(struct file *fp, size_t size, off_t offset, void **memp);
 int	shm_unmap(struct file *fp, void *mem, size_t size);
+void	shm_path(struct shmfd *shmfd, char *path, size_t size);
 
 #else /* !_KERNEL */
 

Modified: stable/8/usr.bin/fstat/fstat.c
==============================================================================
--- stable/8/usr.bin/fstat/fstat.c	Wed Jun  6 21:49:31 2012	(r236698)
+++ stable/8/usr.bin/fstat/fstat.c	Wed Jun  6 21:57:03 2012	(r236699)
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
 #define	_WANT_FILE
 #include <sys/file.h>
 #include <sys/conf.h>
+#include <sys/mman.h>
 #define	_KERNEL
 #include <sys/pipe.h>
 #include <sys/mount.h>
@@ -155,6 +156,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 shmtrans(struct shmfd *shmp, int i, int flag);
 void getinetproto(int number);
 int  getfname(const char *filename);
 void usage(void);
@@ -418,6 +420,12 @@ dofiles(struct kinfo_proc *kp)
 				ptstrans(file.f_data, i, file.f_flag);
 		}
 #endif
+#ifdef DTYPE_SHM
+		else if (file.f_type == DTYPE_SHM) {
+			if (checkfile == 0)
+				shmtrans(file.f_data, i, file.f_flag);
+		}
+#endif
 		else {
 			dprintf(stderr,
 			    "unknown file type %d for file %d of pid %d\n",
@@ -939,6 +947,55 @@ bad:
 	printf("* error\n");
 }
 
+void
+shmtrans(struct shmfd *shmp, int i, int flag)
+{
+	struct shmfd shm;
+	char name[MAXPATHLEN];
+	char mode[15];
+	char rw[3];
+	unsigned j;
+
+	PREFIX(i);
+
+	if (!KVM_READ(shmp, &shm, sizeof(struct shmfd))) {
+		dprintf(stderr, "can't read shm at %p\n", shmp);
+		goto bad;
+	}
+
+	if (shm.shm_path != NULL) {
+		for (j = 0; j < sizeof(name) - 1; j++) {
+			if (!KVM_READ(shm.shm_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");
+
+	shm.shm_mode |= S_IFREG;
+	if (nflg) {
+		printf("             ");
+		(void)snprintf(mode, sizeof(mode), "%o", shm.shm_mode);
+	} else {
+		printf(" %-15s", name[0] != '\0' ? name : "-");
+		strmode(shm.shm_mode, mode);
+	}
+	printf(" %10s %6ju", mode, shm.shm_size);
+	printf(" %2s\n", rw);
+
+	return;
+bad:
+	printf("* error\n");
+}
+
 /*
  * Read the cdev structure in the kernel in order to work out the
  * associated dev_t

Modified: stable/8/usr.bin/procstat/procstat_files.c
==============================================================================
--- stable/8/usr.bin/procstat/procstat_files.c	Wed Jun  6 21:49:31 2012	(r236698)
+++ stable/8/usr.bin/procstat/procstat_files.c	Wed Jun  6 21:57:03 2012	(r236699)
@@ -277,13 +277,6 @@ procstat_files(pid_t pid, struct kinfo_p
 			printf("%7c ", '-');
 
 		switch (kif->kf_type) {
-		case KF_TYPE_VNODE:
-		case KF_TYPE_FIFO:
-		case KF_TYPE_PTS:
-			printf("%-3s ", "-");
-			printf("%-18s", kif->kf_path);
-			break;
-
 		case KF_TYPE_SOCKET:
 			printf("%-3s ",
 			    protocol_to_string(kif->kf_sock_domain,
@@ -312,7 +305,8 @@ procstat_files(pid_t pid, struct kinfo_p
 
 		default:
 			printf("%-3s ", "-");
-			printf("%-18s", "-");
+			printf("%-18s", kif->kf_path[0] != '\0' ?
+			    kif->kf_path : "-");
 		}
 
 		printf("\n");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206062157.q56Lv3a5040780>