svn commit: r195877 - in projects/libprocstat: sys/kern sys/sys
usr.bin/fstat
Stanislav Sedov
stas at FreeBSD.org
Sat Jul 25 20:26:55 UTC 2009
Author: stas
Date: Sat Jul 25 20:26:54 2009
New Revision: 195877
URL: http://svn.freebsd.org/changeset/base/195877
Log:
- Locking bugfixes.
- Organize new kinfo_file fields into the union to save space. Also
use kf_path field for textual representation of sockets domain name.
This allows to fit all new kinfo_fields into spare space thus keeping
the sysctl compatible with 7x world.
- Use uint64_t to store pointers to allow i386 fstat to be used with amd64
kernels and vice versa.
- Correctly initialize kf_vnode_type field.
- Implement missing sysctl-mode access routines in libprocstat. Now sysctl
version of fstat should be fully functional.
Modified:
projects/libprocstat/sys/kern/kern_descrip.c
projects/libprocstat/sys/sys/user.h
projects/libprocstat/usr.bin/fstat/libprocstat.c
projects/libprocstat/usr.bin/fstat/libprocstat.h
Modified: projects/libprocstat/sys/kern/kern_descrip.c
==============================================================================
--- projects/libprocstat/sys/kern/kern_descrip.c Sat Jul 25 19:43:46 2009 (r195876)
+++ projects/libprocstat/sys/kern/kern_descrip.c Sat Jul 25 20:26:54 2009 (r195877)
@@ -2968,6 +2968,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
struct filedesc *fdp;
struct kinfo_file *kif;
struct proc *p;
+ struct vnode *tracevp, *textvp;
size_t oldidx;
int64_t offset;
void *data;
@@ -2981,27 +2982,23 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
PROC_UNLOCK(p);
return (error);
}
+ /* ktrace vnode */
+ tracevp = p->p_tracevp;
+ if (tracevp != NULL)
+ vref(tracevp);
+ /* text vnode */
+ textvp = p->p_textvp;
+ if (textvp != NULL)
+ vref(textvp);
fdp = fdhold(p);
+ PROC_UNLOCK(p);
kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
- /* ktrace vnode */
- if (p->p_tracevp != NULL) {
- vref(p->p_tracevp);
- data = p->p_tracevp;
- PROC_UNLOCK(p);
- export_fd_for_sysctl(data, KF_TYPE_VNODE, KF_FD_TYPE_TRACE,
+ if (tracevp != NULL)
+ export_fd_for_sysctl(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE,
FREAD | FWRITE, -1, -1, kif, req);
- PROC_LOCK(p);
- }
- /* text vnode */
- if (p->p_textvp != NULL) {
- vref(p->p_textvp);
- data = p->p_textvp;
- PROC_UNLOCK(p);
- export_fd_for_sysctl(data, KF_TYPE_VNODE, KF_FD_TYPE_TEXT,
+ if (textvp != NULL)
+ export_fd_for_sysctl(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT,
FREAD, -1, -1, kif, req);
- PROC_LOCK(p);
- }
- PROC_UNLOCK(p);
if (fdp == NULL)
goto fail;
FILEDESC_SLOCK(fdp);
@@ -3133,20 +3130,20 @@ fill_vnode_info(struct vnode *vp, struct
int vtype;
int kf_vtype;
} vtypes_table[] = {
- { VNON, },
- { VREG, },
- { VDIR, },
- { VBLK, },
- { VCHR, },
- { VLNK, },
- { VSOCK, },
- { VFIFO, },
- { VBAD, },
+ { VNON, KF_VTYPE_VNON },
+ { VREG, KF_VTYPE_VREG },
+ { VDIR, KF_VTYPE_VDIR },
+ { VBLK, KF_VTYPE_VBLK },
+ { VCHR, KF_VTYPE_VCHR },
+ { VLNK, KF_VTYPE_VLNK },
+ { VSOCK, KF_VTYPE_VSOCK },
+ { VFIFO, KF_VTYPE_VFIFO },
+ { VBAD, KF_VTYPE_VBAD }
};
#define NVTYPES (sizeof(vtypes_table) / sizeof(*vtypes_table))
struct vattr va;
char *fullpath, *freepath;
- int error;
+ int error, vfslocked;
unsigned int i;
if (vp == NULL)
@@ -3158,7 +3155,6 @@ fill_vnode_info(struct vnode *vp, struct
for (i = 0; i < NVTYPES; i++)
if (vtypes_table[i].vtype == vp->v_type)
break;
-
if (i < NVTYPES)
kif->kf_vnode_type = vtypes_table[i].kf_vtype;
else
@@ -3175,14 +3171,18 @@ fill_vnode_info(struct vnode *vp, struct
/*
* Retrieve vnode attributes.
*/
- error = VOP_GETATTR(vp, &va, NULL);
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &va, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ VFS_UNLOCK_GIANT(vfslocked);
if (error != 0)
return (error);
- kif->kf_file_fsid = va.va_fsid;
- kif->kf_file_fileid = va.va_fileid;
- kif->kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
- kif->kf_file_size = va.va_size;
- kif->kf_file_rdev = va.va_rdev;
+ kif->kf_un.file.kf_file_fsid = va.va_fsid;
+ kif->kf_un.file.kf_file_fileid = va.va_fileid;
+ kif->kf_un.file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
+ kif->kf_un.file.kf_file_size = va.va_size;
+ kif->kf_un.file.kf_file_rdev = va.va_rdev;
return (0);
}
@@ -3199,14 +3199,15 @@ fill_socket_info(struct socket *so, stru
kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
kif->kf_sock_type = so->so_type;
kif->kf_sock_protocol = so->so_proto->pr_protocol;
- kif->kf_sock_pcb = (uint64_t)so->so_pcb;
+ kif->kf_un.sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
switch(kif->kf_sock_domain) {
case AF_INET:
case AF_INET6:
if (kif->kf_sock_protocol == IPPROTO_TCP) {
if (so->so_pcb != NULL) {
inpcb = (struct inpcb *)(so->so_pcb);
- kif->kf_sock_inpcb = (uint64_t)inpcb->inp_ppcb;
+ kif->kf_un.sock.kf_sock_inpcb =
+ (uintptr_t)inpcb->inp_ppcb;
}
}
break;
@@ -3214,11 +3215,11 @@ fill_socket_info(struct socket *so, stru
if (so->so_pcb != NULL) {
unpcb = (struct unpcb *)(so->so_pcb);
if (unpcb->unp_conn) {
- kif->kf_sock_unpconn =
- (uint64_t)unpcb->unp_conn;
- kif->kf_sock_rcv_sb_state =
+ kif->kf_un.sock.kf_sock_unpconn =
+ (uintptr_t)unpcb->unp_conn;
+ kif->kf_un.sock.kf_sock_rcv_sb_state =
so->so_rcv.sb_state;
- kif->kf_sock_snd_sb_state =
+ kif->kf_un.sock.kf_sock_snd_sb_state =
so->so_snd.sb_state;
}
}
@@ -3234,8 +3235,8 @@ fill_socket_info(struct socket *so, stru
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
free(sa, M_SONAME);
}
- strncpy(kif->kf_sock_domname, so->so_proto->pr_domain->dom_name,
- sizeof(kif->kf_sock_domname));
+ strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
+ sizeof(kif->kf_path));
return (0);
}
@@ -3245,6 +3246,7 @@ fill_pts_info(struct tty *tp, struct kin
if (tp == NULL)
return (1);
+ kif->kf_un.pts.pts_dev = tty_udev(tp);
strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
return (0);
}
@@ -3255,9 +3257,9 @@ fill_pipe_info(struct pipe *pi, struct k
if (pi == NULL)
return (1);
- kif->pipe_addr = (uint64_t)pi;
- kif->pipe_peer = (uint64_t)pi->pipe_peer;
- kif->pipe_buffer_cnt = pi->pipe_buffer.cnt;
+ kif->kf_un.pipe.pipe_addr = (uintptr_t)pi;
+ kif->kf_un.pipe.pipe_peer = (uintptr_t)pi->pipe_peer;
+ kif->kf_un.pipe.pipe_buffer_cnt = pi->pipe_buffer.cnt;
return (0);
}
Modified: projects/libprocstat/sys/sys/user.h
==============================================================================
--- projects/libprocstat/sys/sys/user.h Sat Jul 25 19:43:46 2009 (r195876)
+++ projects/libprocstat/sys/sys/user.h Sat Jul 25 20:26:54 2009 (r195877)
@@ -317,7 +317,7 @@ struct kinfo_ofile {
};
#if defined(__amd64__) || defined(__i386__)
-#define KINFO_FILE_SIZE 1496
+#define KINFO_FILE_SIZE 1392
#endif
struct kinfo_file {
@@ -326,29 +326,53 @@ struct kinfo_file {
int kf_fd; /* Array index. */
int kf_ref_count; /* Reference count. */
int kf_flags; /* Flags. */
- int kf_vnode_type; /* Vnode type. */
+ int kf_pad0; /* Round to 64 bit alignment. */
int64_t kf_offset; /* Seek location. */
- char kf_sock_domname[32]; /* Address domain name. */
+ int kf_vnode_type; /* Vnode type. */
int kf_sock_domain; /* Socket domain. */
- int kf_sock_protocol; /* Socket protocol. */
int kf_sock_type; /* Socket type. */
- uint16_t kf_sock_snd_sb_state; /* Send buffer state. */
- uint16_t kf_sock_rcv_sb_state; /* Receive buffer state. */
- uint64_t kf_sock_pcb; /* Address of so_pcb. */
- uint64_t kf_sock_inpcb; /* Address of inp_ppcb. */
- uint64_t kf_sock_unpconn; /* Address of unp_conn. */
+ int kf_sock_protocol; /* Socket protocol. */
struct sockaddr_storage kf_sa_local; /* Socket address. */
struct sockaddr_storage kf_sa_peer; /* Peer address. */
- dev_t kf_file_fsid; /* Vnode filesystem id. */
- dev_t kf_file_rdev; /* File device. */
- uint64_t kf_file_fileid; /* Global file id. */
- off_t kf_file_size; /* File size. */
- mode_t kf_file_mode; /* File mode. */
+ union {
+ struct {
+ /* Send buffer state. */
+ uint16_t kf_sock_snd_sb_state;
+ /* Receive buffer state. */
+ uint16_t kf_sock_rcv_sb_state;
+ /* Address of so_pcb. */
+ uint64_t kf_sock_pcb;
+ /* Address of inp_ppcb. */
+ uint64_t kf_sock_inpcb;
+ /* Address of unp_conn. */
+ uint64_t kf_sock_unpconn;
+ /* Round to 64-bit alignment. */
+ int kf_sock_pad;
+ } sock;
+ struct {
+ /* Vnode filesystem id. */
+ dev_t kf_file_fsid;
+ /* File device. */
+ dev_t kf_file_rdev;
+ /* Global file id. */
+ uint64_t kf_file_fileid;
+ /* File size. */
+ off_t kf_file_size;
+ /* File mode. */
+ mode_t kf_file_mode;
+ } file;
+ struct {
+ uint32_t pipe_buffer_cnt;
+ uint64_t pipe_addr;
+ uint64_t pipe_peer;
+ } pipe;
+ struct {
+ dev_t pts_dev;
+ } pts;
+ } kf_un;
uint16_t kf_status; /* Status flags. */
- uint32_t pipe_buffer_cnt;
- uint64_t pipe_addr;
- uint64_t pipe_peer;
- int _kf_ispare[16]; /* Space for more stuff. */
+ uint16_t kf_pad1; /* Round to 32 bit alignment. */
+ int _kf_ispare[7]; /* Space for more stuff. */
/* Truncated before copyout in sysctl */
char kf_path[PATH_MAX]; /* Path to file, if any. */
};
Modified: projects/libprocstat/usr.bin/fstat/libprocstat.c
==============================================================================
--- projects/libprocstat/usr.bin/fstat/libprocstat.c Sat Jul 25 19:43:46 2009 (r195876)
+++ projects/libprocstat/usr.bin/fstat/libprocstat.c Sat Jul 25 20:26:54 2009 (r195877)
@@ -610,12 +610,10 @@ kinfo_uflags2fst(int fd)
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);
}
@@ -701,8 +699,8 @@ procstat_get_pipe_info_kvm(kvm_t *kd, st
warnx("can't read pipe at %p", (void *)pipep);
goto fail;
}
- ps->addr = (caddr_t)pipep;
- ps->peer = (caddr_t)pi.pipe_peer;
+ ps->addr = (uintptr_t)pipep;
+ ps->peer = (uintptr_t)pi.pipe_peer;
ps->buffer_cnt = pi.pipe_buffer.cnt;
return (0);
@@ -712,13 +710,21 @@ fail:
}
static int
-procstat_get_pipe_info_sysctl(struct filestat *fst __unused, struct pipestat *ps __unused,
+procstat_get_pipe_info_sysctl(struct filestat *fst, struct pipestat *ps,
char *errbuf __unused)
{
+ struct kinfo_file *kif;
- warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
- snprintf(errbuf, _POSIX2_LINE_MAX, "error");
- return (1);
+ assert(ps);
+ assert(fst);
+ bzero(ps, sizeof(*ps));
+ kif = fst->fs_typedep;
+ if (kif == NULL)
+ return (1);
+ ps->addr = kif->kf_un.pipe.pipe_addr;
+ ps->peer = kif->kf_un.pipe.pipe_peer;
+ ps->buffer_cnt = kif->kf_un.pipe.pipe_buffer_cnt;
+ return (0);
}
int
@@ -767,13 +773,20 @@ fail:
}
static int
-procstat_get_pts_info_sysctl(struct filestat *fst __unused, struct ptsstat *pts __unused,
+procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts,
char *errbuf __unused)
{
+ struct kinfo_file *kif;
- warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
- snprintf(errbuf, _POSIX2_LINE_MAX, "error");
- return (1);
+ assert(pts);
+ assert(fst);
+ bzero(pts, sizeof(*pts));
+ kif = fst->fs_typedep;
+ if (kif == NULL)
+ return (0);
+ pts->dev = kif->kf_un.pts.pts_dev;
+ strlcpy(pts->devname, kif->kf_path, sizeof(pts->devname));
+ return (0);
}
int
@@ -893,7 +906,7 @@ procstat_get_vnode_info_sysctl(struct fi
statfs(kif->kf_path, &stbuf);
vn->mntdir = strdup(stbuf.f_mntonname);
}
- vn->vn_dev = kif->kf_file_rdev;
+ 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);
if (name != NULL)
@@ -903,10 +916,10 @@ procstat_get_vnode_info_sysctl(struct fi
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;
+ 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;
return (0);
}
@@ -947,7 +960,7 @@ procstat_get_socket_info_kvm(kvm_t *kd,
so = fst->fs_typedep;
if (so == NULL)
goto fail;
- sock->so_addr = (caddr_t)so;
+ sock->so_addr = (uintptr_t)so;
/* fill in socket */
if (!kvm_read_all(kd, (unsigned long)so, &s,
sizeof(struct socket))) {
@@ -981,7 +994,7 @@ procstat_get_socket_info_kvm(kvm_t *kd,
sock->type = s.so_type;
sock->proto = proto.pr_protocol;
sock->dom_family = dom.dom_family;
- sock->so_pcb = s.so_pcb;
+ sock->so_pcb = (uintptr_t)s.so_pcb;
/*
* Protocol specific data.
@@ -998,7 +1011,7 @@ procstat_get_socket_info_kvm(kvm_t *kd,
(void *)s.so_pcb);
} else
sock->inp_ppcb =
- (caddr_t)inpcb.inp_ppcb;
+ (uintptr_t)inpcb.inp_ppcb;
}
}
break;
@@ -1011,7 +1024,7 @@ procstat_get_socket_info_kvm(kvm_t *kd,
} else if (unpcb.unp_conn) {
sock->so_rcv_sb_state = s.so_rcv.sb_state;
sock->so_snd_sb_state = s.so_snd.sb_state;
- sock->unp_conn = (caddr_t)unpcb.unp_conn;
+ sock->unp_conn = (uintptr_t)unpcb.unp_conn;
}
}
break;
@@ -1026,13 +1039,50 @@ fail:
}
static int
-procstat_get_socket_info_sysctl(struct filestat *fst __unused, struct sockstat *sock __unused,
+procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
char *errbuf __unused)
{
+ struct kinfo_file *kif;
- warnx("not implemented: %s:%d", __FUNCTION__, __LINE__);
- snprintf(errbuf, _POSIX2_LINE_MAX, "error");
- return (1);
+ assert(sock);
+ assert(fst);
+ bzero(sock, sizeof(*sock));
+ kif = fst->fs_typedep;
+ if (kif == NULL)
+ return (0);
+
+ /*
+ * Fill in known data.
+ */
+ sock->type = kif->kf_sock_type;
+ sock->proto = kif->kf_sock_protocol;
+ sock->dom_family = kif->kf_sock_domain;
+ sock->so_pcb = kif->kf_un.sock.kf_sock_pcb;
+ strlcpy(sock->dname, kif->kf_path, sizeof(sock->dname));
+
+ /*
+ * Protocol specific data.
+ */
+ switch(sock->dom_family) {
+ case AF_INET:
+ case AF_INET6:
+ if (sock->proto == IPPROTO_TCP)
+ sock->inp_ppcb = kif->kf_un.sock.kf_sock_inpcb;
+ break;
+ case AF_UNIX:
+ if (kif->kf_un.sock.kf_sock_unpconn != 0) {
+ sock->so_rcv_sb_state =
+ kif->kf_un.sock.kf_sock_rcv_sb_state;
+ sock->so_snd_sb_state =
+ kif->kf_un.sock.kf_sock_snd_sb_state;
+ sock->unp_conn =
+ kif->kf_un.sock.kf_sock_unpconn;
+ }
+ break;
+ default:
+ break;
+ }
+ return (0);
}
static int
Modified: projects/libprocstat/usr.bin/fstat/libprocstat.h
==============================================================================
--- projects/libprocstat/usr.bin/fstat/libprocstat.h Sat Jul 25 19:43:46 2009 (r195876)
+++ projects/libprocstat/usr.bin/fstat/libprocstat.h Sat Jul 25 20:26:54 2009 (r195877)
@@ -115,21 +115,21 @@ struct ptsstat {
char devname[SPECNAMELEN + 1];
};
struct pipestat {
- caddr_t addr;
- caddr_t peer;
- size_t buffer_cnt;
+ uint64_t addr;
+ uint64_t peer;
+ size_t buffer_cnt;
};
struct sockstat {
- int type;
- int proto;
- int dom_family;
- caddr_t so_addr;
- caddr_t so_pcb;
- caddr_t inp_ppcb;
- caddr_t unp_conn;
- int so_snd_sb_state;
- int so_rcv_sb_state;
- char dname[32];
+ int type;
+ int proto;
+ int dom_family;
+ uint64_t so_addr;
+ uint64_t so_pcb;
+ uint64_t inp_ppcb;
+ uint64_t unp_conn;
+ int so_snd_sb_state;
+ int so_rcv_sb_state;
+ char dname[32];
};
/* XXX: sort structs. */
More information about the svn-src-projects
mailing list