Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Jul 2009 11:17:54 +0000 (UTC)
From:      Stanislav Sedov <stas@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r195781 - projects/libprocstat/usr.bin/fstat
Message-ID:  <200907201117.n6KBHsjm076646@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: stas
Date: Mon Jul 20 11:17:54 2009
New Revision: 195781
URL: http://svn.freebsd.org/changeset/base/195781

Log:
  - Add sysctl-based access routines (unfinished).

Modified:
  projects/libprocstat/usr.bin/fstat/Makefile
  projects/libprocstat/usr.bin/fstat/libprocstat.c
  projects/libprocstat/usr.bin/fstat/libprocstat.h

Modified: projects/libprocstat/usr.bin/fstat/Makefile
==============================================================================
--- projects/libprocstat/usr.bin/fstat/Makefile	Mon Jul 20 10:27:47 2009	(r195780)
+++ projects/libprocstat/usr.bin/fstat/Makefile	Mon Jul 20 11:17:54 2009	(r195781)
@@ -8,7 +8,7 @@ SRCS=	cd9660.c common_kvm.c fstat.c fuse
 LINKS=	${BINDIR}/fstat ${BINDIR}/fuser
 DPADD=	${LIBKVM}
 LDADD=	-lkvm -lutil
-WARNS?=	3
+WARNS?=	6
 
 MAN1=	fuser.1 fstat.1
 

Modified: projects/libprocstat/usr.bin/fstat/libprocstat.c
==============================================================================
--- projects/libprocstat/usr.bin/fstat/libprocstat.c	Mon Jul 20 10:27:47 2009	(r195780)
+++ projects/libprocstat/usr.bin/fstat/libprocstat.c	Mon Jul 20 11:17:54 2009	(r195781)
@@ -95,24 +95,45 @@ __FBSDID("$FreeBSD$");
 #include "libprocstat.h"
 #include "common_kvm.h"
 
+int     statfs(const char *, struct statfs *);	/* XXX */
+
 /*
  * Vnode-to-filestat types translation table.
  */
 static struct {
-        int     vtype; 
-        int     fst_vtype;
+	int	vtype; 
+	int	fst_vtype;
 } vt2fst[] = {
-        { VNON, PS_FST_VTYPE_VNON },
-        { VREG, PS_FST_VTYPE_VREG },
-        { VDIR, PS_FST_VTYPE_VDIR },
-        { VBLK, PS_FST_VTYPE_VBLK },
-        { VCHR, PS_FST_VTYPE_VCHR },
-        { VLNK, PS_FST_VTYPE_VLNK },
-        { VSOCK, PS_FST_VTYPE_VSOCK },
-        { VFIFO, PS_FST_VTYPE_VFIFO },
-        { VBAD, PS_FST_VTYPE_VBAD }
+	{ VNON, PS_FST_VTYPE_VNON },
+	{ VREG, PS_FST_VTYPE_VREG },
+	{ VDIR, PS_FST_VTYPE_VDIR },
+	{ VBLK, PS_FST_VTYPE_VBLK },
+	{ VCHR, PS_FST_VTYPE_VCHR },
+	{ VLNK, PS_FST_VTYPE_VLNK },
+	{ VSOCK, PS_FST_VTYPE_VSOCK },
+	{ VFIFO, PS_FST_VTYPE_VFIFO },
+	{ VBAD, PS_FST_VTYPE_VBAD }
+};
+#define	NVFTYPES	(sizeof(vt2fst) / sizeof(*vt2fst))
+
+/*
+ * kinfo tof ilestat vnode types translation table.
+ */
+static struct {
+	int	kf_vtype; 
+	int	fst_vtype;
+} kfvtypes2fst[] = {
+	{ KF_VTYPE_VNON, PS_FST_VTYPE_VNON },
+	{ KF_VTYPE_VREG, PS_FST_VTYPE_VREG },
+	{ KF_VTYPE_VDIR, PS_FST_VTYPE_VDIR },
+	{ KF_VTYPE_VBLK, PS_FST_VTYPE_VBLK },
+	{ KF_VTYPE_VCHR, PS_FST_VTYPE_VCHR },
+	{ KF_VTYPE_VLNK, PS_FST_VTYPE_VLNK },
+	{ KF_VTYPE_VSOCK, PS_FST_VTYPE_VSOCK },
+	{ KF_VTYPE_VFIFO, PS_FST_VTYPE_VFIFO },
+	{ KF_VTYPE_VBAD, PS_FST_VTYPE_VBAD }
 };
-#define NVFTYPES (sizeof(vt2fst) / sizeof(*vt2fst))
+#define	NKFVTYPES	(sizeof(kfvtypes2fst) / sizeof(*kfvtypes2fst))
 
 /*
  * Descriptor-to-filestat flags translation table.
@@ -139,6 +160,47 @@ static struct {
 #define NFSTFLAGS	(sizeof(fstflags) / sizeof(*fstflags))
 
 /*
+ * kinfo types to filestat translation table.
+ */
+static struct {
+	int kf_type;
+	int fst_type;
+} kftypes2fst[] = {
+	{ KF_TYPE_NONE, PS_FST_TYPE_NONE },
+	{ KF_TYPE_VNODE, PS_FST_TYPE_VNODE },
+	{ KF_TYPE_SOCKET, PS_FST_TYPE_SOCKET },
+	{ KF_TYPE_PIPE, PS_FST_TYPE_PIPE },
+	{ KF_TYPE_FIFO, PS_FST_TYPE_FIFO },
+	{ KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE },
+	{ KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO },
+	{ KF_TYPE_MQUEUE, PS_FST_TYPE_MQUEUE },
+	{ KF_TYPE_SHM, PS_FST_TYPE_SHM },
+	{ KF_TYPE_SEM, PS_FST_TYPE_SEM },
+	{ KF_TYPE_PTS, PS_FST_TYPE_PTS },
+	{ KF_TYPE_UNKNOWN, PS_FST_TYPE_UNKNOWN }
+};
+#define NKFTYPES	(sizeof(kftypes2fst) / sizeof(*kftypes2fst))
+
+/*
+ * kinfo flags to filestat translation table.
+ */
+static struct {
+	int kf_flag;
+	int fst_flag;
+} kfflags2fst[] = {
+	{ KF_FLAG_READ, PS_FST_FFLAG_READ },
+	{ KF_FLAG_WRITE, PS_FST_FFLAG_WRITE },
+	{ KF_FLAG_NONBLOCK, PS_FST_FFLAG_NONBLOCK },
+	{ KF_FLAG_APPEND, PS_FST_FFLAG_APPEND },
+	{ KF_FLAG_HASLOCK, PS_FST_FFLAG_SHLOCK },	/* XXX: which lock? */
+	{ KF_FLAG_ASYNC, PS_FST_FFLAG_ASYNC },
+	{ KF_FLAG_FSYNC, PS_FST_FFLAG_SYNC },
+	{ KF_FLAG_DIRECT, PS_FST_FFLAG_DIRECT },
+	/* XXX: other types? */
+};
+#define NKFFLAGS	(sizeof(kfflags2fst) / sizeof(*kfflags2fst))
+
+/*
  * Filesystem specific handlers.
  */
 #define FSTYPE(fst)     {#fst, fst##_filestat}
@@ -306,7 +368,7 @@ procstat_getfiles(struct procstat *procs
 }
 
 static struct filestat *
-filestat_new_entry(struct vnode *vp, int type, int fd, int fflags, int uflags)
+filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags)
 {
 	struct filestat *entry;
 
@@ -315,7 +377,7 @@ filestat_new_entry(struct vnode *vp, int
 		warn("malloc()");
 		return (NULL);
 	}
-	entry->fs_typedep = vp;
+	entry->fs_typedep = typedep;
 	entry->fs_fflags = fflags;
 	entry->fs_uflags = uflags;
 	entry->fs_fd = fd;
@@ -512,10 +574,95 @@ exit:
 	return (head);
 }
 
+static int
+kinfo_type2fst(int kftype)
+{
+	unsigned int i;
+
+	for (i = 0; i < NKFTYPES; i++)
+		if (kftypes2fst[i].kf_type == kftype)
+			break;
+	if (i == NKFTYPES)
+		return (PS_FST_TYPE_UNKNOWN);
+	return (kftypes2fst[i].fst_type);
+}
+
+static int
+kinfo_fflags2fst(int kfflags)
+{
+	unsigned int i;
+	int flags;
+
+	flags = 0;
+	for (i = 0; i < NKFFLAGS; i++)
+		if ((kfflags & kfflags2fst[i].kf_flag) != 0)
+			flags |= kfflags2fst[i].fst_flag;
+	return (flags);
+}
+
+static int
+kinfo_uflags2fst(int fd)
+{
+	switch (fd) {
+	case KF_FD_TYPE_CWD:
+		return (PS_FST_UFLAG_CDIR);
+	case KF_FD_TYPE_ROOT:
+		return (PS_FST_UFLAG_RDIR);
+	case KF_FD_TYPE_JAIL:
+		return (PS_FST_UFLAG_JAIL);
+#if 0
+	case KF_FD_TYPE_TRACE:
+		return (PS_FST_UFLAG_TRACE);
+	case KF_FD_TYPE_TEXT:
+		return (PS_FST_UFLAG_TEXT);
+#endif
+	}
+	return (0);
+}
+
 static struct filestat_list *
-procstat_getfiles_sysctl(struct kinfo_proc *kp __unused, int mmapped)
+procstat_getfiles_sysctl(struct kinfo_proc *kp, int mmapped __unused)
 {
-	return (NULL);
+	struct kinfo_file *kif, *files;
+	struct filestat_list *head;
+	int fd, fflags, uflags, type;
+	struct filestat *entry;
+	int cnt, i;
+
+	assert(kp);
+
+	if (kp->ki_fd == NULL)
+		return (NULL);
+
+	files = kinfo_getfile(kp->ki_pid, &cnt);
+	if (files == NULL) {
+		warn("kinfo_getfile()");
+		return (NULL);
+	}
+
+	/*
+	 * Allocate list head.
+	 */
+	head = malloc(sizeof(*head));
+	if (head == NULL)
+		return (NULL);
+	STAILQ_INIT(head);
+	for (i = 0; i < cnt; i++) {
+		kif = &files[i];
+
+		type = kinfo_type2fst(kif->kf_type);
+		fd = kif->kf_fd >= 0 ? kif->kf_fd : -1;
+		fflags = kinfo_fflags2fst(kif->kf_flags);
+		uflags = kinfo_uflags2fst(kif->kf_fd);
+
+		/*
+		 * Create filestat entry.
+		 */
+		entry = filestat_new_entry(kif, type, fd, fflags, uflags);
+		if (entry != NULL)
+			STAILQ_INSERT_TAIL(head, entry, next);
+	}
+	return (head);
 }
 
 int
@@ -565,8 +712,8 @@ fail:
 }
 
 static int
-procstat_get_pipe_info_sysctl(struct filestat *fst, struct pipestat *ps,
-    char *errbuf)
+procstat_get_pipe_info_sysctl(struct filestat *fst __unused, struct pipestat *ps __unused,
+    char *errbuf __unused)
 {
 
 	warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
@@ -620,8 +767,8 @@ fail:
 }
 
 static int
-procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts,
-    char *errbuf)
+procstat_get_pts_info_sysctl(struct filestat *fst __unused, struct ptsstat *pts __unused,
+    char *errbuf __unused)
 {
 
 	warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
@@ -711,13 +858,56 @@ fail:
 }
 
 static int
+kinfo_vtype2fst(int kfvtype)
+{
+	unsigned int i;
+
+	for (i = 0; i < NKFVTYPES; i++)
+		if (kfvtypes2fst[i].kf_vtype == kfvtype)
+			break;
+	if (i == NKFVTYPES)
+		return (PS_FST_VTYPE_UNKNOWN);
+	return (kfvtypes2fst[i].fst_vtype);
+}
+
+static int
 procstat_get_vnode_info_sysctl(struct filestat *fst, struct vnstat *vn,
-    char *errbuf)
+    char *errbuf __unused)
 {
+	struct kinfo_file *kif;
+	struct statfs stbuf;
+	char *name;
 
-	warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
-	snprintf(errbuf, _POSIX2_LINE_MAX, "error");
-	return (1);
+	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)
+		return (0);
+	if (kif->kf_path && *kif->kf_path) {
+		statfs(kif->kf_path, &stbuf);
+		vn->mntdir = strdup(stbuf.f_mntonname);
+	}
+	vn->vn_dev = kif->kf_file_rdev;
+	if (kif->kf_vnode_type == KF_VTYPE_VBLK) {
+		name = devname(vn->vn_dev, S_IFBLK);
+		if (name != NULL)
+			strlcpy(vn->vn_devname, name, sizeof(vn->vn_devname));
+	} else if (kif->kf_vnode_type == KF_VTYPE_VCHR) {
+		name = devname(vn->vn_dev, S_IFCHR);
+		if (name != NULL)
+			strlcpy(vn->vn_devname, name, sizeof(vn->vn_devname));
+	}
+	vn->vn_fsid = kif->kf_file_fsid;
+	vn->vn_fileid = kif->kf_file_fileid;
+	vn->vn_size = kif->kf_file_size;
+	vn->vn_mode = kif->kf_file_mode;
+	return (0);
 }
 
 int
@@ -836,8 +1026,8 @@ fail:
 }
 
 static int
-procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
-    char *errbuf)
+procstat_get_socket_info_sysctl(struct filestat *fst __unused, struct sockstat *sock __unused,
+    char *errbuf __unused)
 {
 
 	warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);

Modified: projects/libprocstat/usr.bin/fstat/libprocstat.h
==============================================================================
--- projects/libprocstat/usr.bin/fstat/libprocstat.h	Mon Jul 20 10:27:47 2009	(r195780)
+++ projects/libprocstat/usr.bin/fstat/libprocstat.h	Mon Jul 20 11:17:54 2009	(r195781)
@@ -51,6 +51,13 @@
 #define	PS_FST_TYPE_SOCKET	3
 #define	PS_FST_TYPE_PIPE	4
 #define	PS_FST_TYPE_PTS		5
+#define	PS_FST_TYPE_KQUEUE	6
+#define	PS_FST_TYPE_CRYPTO	7
+#define	PS_FST_TYPE_MQUEUE	8
+#define	PS_FST_TYPE_SHM		9
+#define	PS_FST_TYPE_SEM		10
+#define	PS_FST_TYPE_UNKNOWN	11
+#define	PS_FST_TYPE_NONE	12
 
 /*
  * Special descriptor numbers.



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