svn commit: r195924 - in projects/libprocstat: sys/kern sys/sys usr.bin/fstat

Stanislav Sedov stas at FreeBSD.org
Tue Jul 28 21:18:27 UTC 2009


Author: stas
Date: Tue Jul 28 21:18:26 2009
New Revision: 195924
URL: http://svn.freebsd.org/changeset/base/195924

Log:
  - Imeplement mmaped files access via sysctl.

Modified:
  projects/libprocstat/sys/kern/kern_descrip.c
  projects/libprocstat/sys/kern/kern_proc.c
  projects/libprocstat/sys/sys/user.h
  projects/libprocstat/usr.bin/fstat/libprocstat.c

Modified: projects/libprocstat/sys/kern/kern_descrip.c
==============================================================================
--- projects/libprocstat/sys/kern/kern_descrip.c	Tue Jul 28 19:58:07 2009	(r195923)
+++ projects/libprocstat/sys/kern/kern_descrip.c	Tue Jul 28 21:18:26 2009	(r195924)
@@ -3123,8 +3123,8 @@ fail:
 	return (error);
 }
 
-static int
-fill_vnode_info(struct vnode *vp, struct kinfo_file *kif)
+int
+vntype_to_kinfo(int vtype)
 {
 	struct {
 		int	vtype;
@@ -3141,25 +3141,30 @@ fill_vnode_info(struct vnode *vp, struct
 		{ VBAD, KF_VTYPE_VBAD }
 	};
 #define	NVTYPES	(sizeof(vtypes_table) / sizeof(*vtypes_table))
-	struct vattr va;
-	char *fullpath, *freepath;
-	int error, vfslocked;
 	unsigned int i;
 
-	if (vp == NULL)
-		return (1);
-
 	/*
 	 * Perform vtype translation.
 	 */
 	for (i = 0; i < NVTYPES; i++)
-		if (vtypes_table[i].vtype == vp->v_type)
+		if (vtypes_table[i].vtype == vtype)
 			break;
 	if (i < NVTYPES)
-		kif->kf_vnode_type = vtypes_table[i].kf_vtype;
-	else
-		kif->kf_vnode_type = KF_VTYPE_UNKNOWN;
+		return (vtypes_table[i].kf_vtype);
+
+	return (KF_VTYPE_UNKNOWN);
+}
 
+static int
+fill_vnode_info(struct vnode *vp, struct kinfo_file *kif)
+{
+	struct vattr va;
+	char *fullpath, *freepath;
+	int error, vfslocked;
+
+	if (vp == NULL)
+		return (1);
+	kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
 	freepath = NULL;
 	fullpath = "-";
 	error = vn_fullpath(curthread, vp, &fullpath, &freepath);

Modified: projects/libprocstat/sys/kern/kern_proc.c
==============================================================================
--- projects/libprocstat/sys/kern/kern_proc.c	Tue Jul 28 19:58:07 2009	(r195923)
+++ projects/libprocstat/sys/kern/kern_proc.c	Tue Jul 28 21:18:26 2009	(r195924)
@@ -1640,8 +1640,6 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
 		last_timestamp = map->timestamp;
 		vm_map_unlock_read(map);
 
-		kve->kve_fileid = 0;
-		kve->kve_fsid = 0;
 		freepath = NULL;
 		fullpath = "";
 		if (lobj) {
@@ -1683,12 +1681,18 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
 			if (vp != NULL) {
 				vn_fullpath(curthread, vp, &fullpath,
 				    &freepath);
+				kve->kve_vn_type = vntype_to_kinfo(vp->v_type);
 				cred = curthread->td_ucred;
 				vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 				vn_lock(vp, LK_SHARED | LK_RETRY);
 				if (VOP_GETATTR(vp, &va, cred) == 0) {
-					kve->kve_fileid = va.va_fileid;
-					kve->kve_fsid = va.va_fsid;
+					kve->kve_vn_fileid = va.va_fileid;
+					kve->kve_vn_fsid = va.va_fsid;
+					kve->kve_vn_mode =
+					    MAKEIMODE(va.va_type, va.va_mode);
+					kve->kve_vn_size = va.va_size;
+					kve->kve_vn_rdev = va.va_rdev;
+					kve->kve_status = KF_ATTR_VALID;
 				}
 				vput(vp);
 				VFS_UNLOCK_GIANT(vfslocked);

Modified: projects/libprocstat/sys/sys/user.h
==============================================================================
--- projects/libprocstat/sys/sys/user.h	Tue Jul 28 19:58:07 2009	(r195923)
+++ projects/libprocstat/sys/sys/user.h	Tue Jul 28 21:18:26 2009	(r195924)
@@ -434,16 +434,21 @@ struct kinfo_vmentry {
 	uint64_t kve_start;			/* Starting address. */
 	uint64_t kve_end;			/* Finishing address. */
 	uint64_t kve_offset;			/* Mapping offset in object */
-	uint64_t kve_fileid;			/* inode number if vnode */
-	uint32_t kve_fsid;			/* dev_t of vnode location */
+	uint64_t kve_vn_fileid;			/* inode number if vnode */
+	uint32_t kve_vn_fsid;			/* dev_t of vnode location */
 	int	 kve_flags;			/* Flags on map entry. */
 	int	 kve_resident;			/* Number of resident pages. */
 	int	 kve_private_resident;		/* Number of private pages. */
 	int	 kve_protection;		/* Protection bitmask. */
 	int	 kve_ref_count;			/* VM obj ref count. */
 	int	 kve_shadow_count;		/* VM obj shadow count. */
+	int	 kve_vn_type;			/* Vnode type. */
+	off_t 	 kve_vn_size;			/* File size. */
+	dev_t	 kve_vn_rdev;			/* Device id if device. */
+	mode_t	 kve_vn_mode;			/* File mode. */
+	uint16_t kve_status;			/* Status flags. */
 	int	 _kve_pad0;			/* 64bit align next field */
-	int	 _kve_ispare[16];		/* Space for more stuff. */
+	int	 _kve_ispare[11];		/* Space for more stuff. */
 	/* Truncated before copyout in sysctl */
 	char	 kve_path[PATH_MAX];		/* Path to VM obj, if any. */
 };
@@ -470,4 +475,8 @@ struct kinfo_kstack {
 	int	 _kkst_ispare[16];		/* Space for more stuff. */
 };
 
+#ifdef _KERNEL
+int	vntype_to_kinfo(int vtype);
+#endif /* !_KERNEL */
+
 #endif

Modified: projects/libprocstat/usr.bin/fstat/libprocstat.c
==============================================================================
--- projects/libprocstat/usr.bin/fstat/libprocstat.c	Tue Jul 28 19:58:07 2009	(r195923)
+++ projects/libprocstat/usr.bin/fstat/libprocstat.c	Tue Jul 28 21:18:26 2009	(r195924)
@@ -528,9 +528,10 @@ kinfo_uflags2fst(int fd)
 }
 
 static struct filestat_list *
-procstat_getfiles_sysctl(struct kinfo_proc *kp, int mmapped __unused)
+procstat_getfiles_sysctl(struct kinfo_proc *kp, int mmapped)
 {
 	struct kinfo_file *kif, *files;
+	struct kinfo_vmentry *kve, *vmentries;
 	struct filestat_list *head;
 	struct filestat *entry;
 	int cnt, fd, fflags;
@@ -568,6 +569,26 @@ procstat_getfiles_sysctl(struct kinfo_pr
 		if (entry != NULL)
 			STAILQ_INSERT_TAIL(head, entry, next);
 	}
+	if (mmapped != 0) {
+		vmentries = kinfo_getvmmap(kp->ki_pid, &cnt);
+		if (vmentries == NULL || cnt == 0)
+			goto fail;
+		for (i = 0; i < cnt; i++) {
+			kve = &vmentries[i];
+			if (kve->kve_type != KVME_TYPE_VNODE)
+				continue;
+			fflags = 0;
+			if (kve->kve_protection & KVME_PROT_READ)
+				fflags = PS_FST_FFLAG_READ;
+			if (kve->kve_protection & KVME_PROT_WRITE)
+				fflags |= PS_FST_FFLAG_WRITE;
+			entry = filestat_new_entry(kve, PS_FST_TYPE_VNODE, -1,
+			    fflags, PS_FST_UFLAG_MMAP);
+			if (entry != NULL)
+				STAILQ_INSERT_TAIL(head, entry, next);
+		}
+	}
+fail:
 	return (head);
 }
 
@@ -835,37 +856,66 @@ procstat_get_vnode_info_sysctl(struct fi
 {
 	struct statfs stbuf;
 	struct kinfo_file *kif;
-	char *name;
+	struct kinfo_vmentry *kve;
+	int vntype;
+	dev_t rdev;
+	off_t size;
+	mode_t mode;
+	int status;
+	uint64_t fileid;
+	uint32_t fsid;
+	char *name, *path;
 
 	assert(fst);
 	assert(vn);
-	kif = fst->fs_typedep;
-	if (kif == NULL)
-		return (1);
 	bzero(vn, sizeof(*vn));
-	vn->vn_type = kinfo_vtype2fst(kif->kf_vnode_type);
-	if (vn->vn_type == PS_FST_VTYPE_VNON ||
-	    vn->vn_type == PS_FST_VTYPE_VBAD ||
-	    (kif->kf_status & KF_ATTR_VALID) == 0)
+	if (fst->fs_typedep == NULL)
+		return (1);
+	if (fst->fs_uflags & PS_FST_UFLAG_MMAP) {
+		kve = fst->fs_typedep;
+		fileid = kve->kve_vn_fileid;
+		fsid = kve->kve_vn_fsid;
+		mode = kve->kve_vn_mode;
+		path = kve->kve_path;
+		rdev = kve->kve_vn_rdev;
+		size = kve->kve_vn_size;
+		vntype = kinfo_vtype2fst(kve->kve_vn_type);
+		status = kve->kve_status;
+	} else {
+		kif = fst->fs_typedep;
+		fileid = kif->kf_un.file.kf_file_fileid;
+		fsid = kif->kf_un.file.kf_file_fsid;
+		mode = kif->kf_un.file.kf_file_mode;
+		path = kif->kf_path;
+		rdev = kif->kf_un.file.kf_file_rdev;
+		size = kif->kf_un.file.kf_file_size;
+		vntype = kinfo_vtype2fst(kif->kf_vnode_type);
+		status = kif->kf_status;
+	}
+	vn->vn_type = vntype;
+	if (vntype == PS_FST_VTYPE_VNON || vntype == PS_FST_VTYPE_VBAD ||
+	    (status & KF_ATTR_VALID) == 0)
 		return (0);
-	if (kif->kf_path && *kif->kf_path) {
-		statfs(kif->kf_path, &stbuf);
+	if (path && *path) {
+		statfs(path, &stbuf);
 		vn->mntdir = strdup(stbuf.f_mntonname);
 	}
-	vn->vn_dev = kif->kf_un.file.kf_file_rdev;
-	if (kif->kf_vnode_type == KF_VTYPE_VBLK) {
-		name = devname(vn->vn_dev, S_IFBLK);
+	vn->vn_dev =rdev;
+	if (vntype == KF_VTYPE_VBLK) {
+		name = devname(rdev, S_IFBLK);
 		if (name != NULL)
-			strlcpy(vn->vn_devname, name, sizeof(vn->vn_devname));
-	} else if (kif->kf_vnode_type == KF_VTYPE_VCHR) {
+			strlcpy(vn->vn_devname, name,
+			    sizeof(vn->vn_devname));
+	} else if (vntype == KF_VTYPE_VCHR) {
 		name = devname(vn->vn_dev, S_IFCHR);
 		if (name != NULL)
-			strlcpy(vn->vn_devname, name, sizeof(vn->vn_devname));
+			strlcpy(vn->vn_devname, name,
+			    sizeof(vn->vn_devname));
 	}
-	vn->vn_fsid = kif->kf_un.file.kf_file_fsid;
-	vn->vn_fileid = kif->kf_un.file.kf_file_fileid;
-	vn->vn_size = kif->kf_un.file.kf_file_size;
-	vn->vn_mode = kif->kf_un.file.kf_file_mode;
+	vn->vn_fsid = fsid;
+	vn->vn_fileid = fileid;
+	vn->vn_size = size;
+	vn->vn_mode = mode;
 	return (0);
 }
 


More information about the svn-src-projects mailing list