Date: Sat, 25 Jul 2009 20:26:54 +0000 (UTC) From: Stanislav Sedov <stas@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195877 - in projects/libprocstat: sys/kern sys/sys usr.bin/fstat Message-ID: <200907252026.n6PKQsnI050352@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907252026.n6PKQsnI050352>