summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/ps/keyword.c3
-rw-r--r--bin/ps/ps.16
-rw-r--r--include/kvm.h13
-rw-r--r--lib/libkvm/Makefile4
-rw-r--r--lib/libkvm/kvm_file2.c43
-rw-r--r--lib/libkvm/kvm_getprocs.332
-rw-r--r--lib/libkvm/kvm_proc.c14
-rw-r--r--lib/libkvm/kvm_proc2.c23
-rw-r--r--lib/libkvm/shlib_version2
-rw-r--r--sys/kern/kern_sysctl.c13
-rw-r--r--sys/sys/proc.h5
-rw-r--r--sys/sys/sysctl.h28
-rw-r--r--usr.bin/fstat/fstat.121
-rw-r--r--usr.bin/fstat/fstat.c236
14 files changed, 276 insertions, 167 deletions
diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index 9a6457b6772..df81cdf948b 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: keyword.c,v 1.34 2011/12/29 17:13:55 guenther Exp $ */
+/* $OpenBSD: keyword.c,v 1.35 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: keyword.c,v 1.12.6.1 1996/05/30 21:25:13 cgd Exp $ */
/*-
@@ -146,6 +146,7 @@ VAR var[] = {
{"rss", "RSS", NULL, 0, p_rssize, 5},
{"rssize", "", "rsz"},
{"rsz", "RSZ", NULL, 0, rssize, 4},
+ {"rtable", "RTABLE", NULL, 0, pvar, 0, 0, POFF(p_rtableid), INT32, "d"},
UID("ruid", "RUID", pvar, POFF(p_ruid)),
{"ruser", "RUSER", NULL, LJUST, runame, USERLEN},
{"sess", "SESS", NULL, 0, pvar, PTRWIDTH, 0, POFF(p_sess), UINT64, "llx"},
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index f26b16649e8..c16a15e3b44 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ps.1,v 1.80 2011/12/16 17:13:18 jmc Exp $
+.\" $OpenBSD: ps.1,v 1.81 2012/01/07 05:38:12 guenther Exp $
.\" $NetBSD: ps.1,v 1.16 1996/03/21 01:36:28 jtc Exp $
.\"
.\" Copyright (c) 1980, 1990, 1991, 1993, 1994
@@ -30,7 +30,7 @@
.\"
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\"
-.Dd $Mdocdate: December 16 2011 $
+.Dd $Mdocdate: January 7 2012 $
.Dt PS 1
.Os
.Sh NAME
@@ -338,6 +338,8 @@ The real memory (resident set) size of the process (in 1024 byte units).
Alias:
.Cm rssize .
Resident set size + (text size / text use count).
+.It Cm rtable
+Routing table.
.It Cm ruid
Real user ID.
.It Cm ruser
diff --git a/include/kvm.h b/include/kvm.h
index b490863f1e5..a1836452da2 100644
--- a/include/kvm.h
+++ b/include/kvm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm.h,v 1.15 2011/03/12 04:54:28 guenther Exp $ */
+/* $OpenBSD: kvm.h,v 1.16 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: kvm.h,v 1.7 1996/04/19 12:02:50 leo Exp $ */
/*-
@@ -76,17 +76,6 @@ ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t)
ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t)
__attribute__((__bounded__(__buffer__,3,4)));
-/*
- * Old names that will disappear in a few revisions
- */
-#ifndef kinfo_proc2
-#define kinfo_proc2 kinfo_proc
-#endif
-char **kvm_getargv2(kvm_t *, const struct kinfo_proc *, int);
-char **kvm_getenvv2(kvm_t *, const struct kinfo_proc *, int);
-struct kinfo_proc *
- kvm_getproc2(kvm_t *, int, int, size_t, int *);
-
__END_DECLS
#endif /* !_KVM_H_ */
diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile
index 1debf0ff158..c56049c3f1d 100644
--- a/lib/libkvm/Makefile
+++ b/lib/libkvm/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.14 2010/02/03 20:49:00 miod Exp $
+# $OpenBSD: Makefile,v 1.15 2012/01/07 05:38:12 guenther Exp $
# $NetBSD: Makefile,v 1.11 1996/03/18 22:33:07 thorpej Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/4/93
@@ -27,8 +27,6 @@ MAN= kvm.3 kvm_dump.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 \
kvm_getprocs.3 kvm_nlist.3 kvm_open.3 kvm_read.3
MLINKS+=kvm_getprocs.3 kvm_getargv.3 kvm_getprocs.3 kvm_getenvv.3
-MLINKS+=kvm_getprocs.3 kvm_getproc2.3
-MLINKS+=kvm_getprocs.3 kvm_getargv2.3 kvm_getprocs.3 kvm_getenvv2.3
MLINKS+=kvm_getfiles.3 kvm_getfile2.3
MLINKS+=kvm_open.3 kvm_openfiles.3 kvm_open.3 kvm_close.3
MLINKS+=kvm_read.3 kvm_write.3
diff --git a/lib/libkvm/kvm_file2.c b/lib/libkvm/kvm_file2.c
index b39d85443fb..37b8485b883 100644
--- a/lib/libkvm/kvm_file2.c
+++ b/lib/libkvm/kvm_file2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_file2.c,v 1.18 2011/12/14 17:33:46 guenther Exp $ */
+/* $OpenBSD: kvm_file2.c,v 1.19 2012/01/07 05:38:12 guenther Exp $ */
/*
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -119,7 +119,7 @@ static struct kinfo_file2 *kvm_deadfile2_byfile(kvm_t *, int, int,
static struct kinfo_file2 *kvm_deadfile2_byid(kvm_t *, int, int,
size_t, int *);
static int fill_file2(kvm_t *, struct kinfo_file2 *, struct file *,
- struct vnode *, struct proc *, int);
+ struct vnode *, struct proc *, int, pid_t);
static int filestat(kvm_t *, struct kinfo_file2 *, struct vnode *);
LIST_HEAD(proclist, proc);
@@ -242,7 +242,7 @@ kvm_deadfile2_byfile(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
where += sizeof(struct kinfo_file2);
buflen -= sizeof(struct kinfo_file2);
n++;
- if (fill_file2(kd, kf, fp, NULL, NULL, 0) == -1)
+ if (fill_file2(kd, kf, fp, NULL, NULL, 0, 0) == -1)
return (NULL);
}
if (n != nfiles) {
@@ -266,11 +266,12 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
struct filedesc0 filed0;
#define filed filed0.fd_fd
struct proclist allproc;
- struct proc *p, proc;
+ struct proc *p, proc, proc2;
struct process process;
struct pcred pcred;
struct ucred ucred;
int i, nfiles, nprocs;
+ pid_t pid;
nl[0].n_name = "_filehead";
nl[1].n_name = "_nfiles";
@@ -341,6 +342,17 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
return (NULL);
}
proc.p_p = &process;
+ if ((proc.p_flag & P_THREAD) == 0)
+ pid = proc.p_pid;
+ else {
+ if (KREAD(kd, (u_long)process.ps_mainproc, &proc2)) {
+ _kvm_err(kd, kd->program,
+ "can't read proc at %x",
+ process.ps_mainproc);
+ return (NULL);
+ }
+ pid = proc2.p_pid;
+ }
if (KREAD(kd, (u_long)process.ps_cred, &pcred) == 0)
KREAD(kd, (u_long)pcred.pc_ucred, &ucred);
@@ -362,7 +374,7 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
buflen -= sizeof(struct kinfo_file2);
n++;
if (fill_file2(kd, kf, NULL, proc.p_textvp, &proc,
- KERN_FILE_TEXT) == -1)
+ KERN_FILE_TEXT, pid) == -1)
return (NULL);
}
if (filed.fd_cdir) {
@@ -373,7 +385,7 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
buflen -= sizeof(struct kinfo_file2);
n++;
if (fill_file2(kd, kf, NULL, filed.fd_cdir, &proc,
- KERN_FILE_CDIR) == -1)
+ KERN_FILE_CDIR, pid) == -1)
return (NULL);
}
if (filed.fd_rdir) {
@@ -384,7 +396,7 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
buflen -= sizeof(struct kinfo_file2);
n++;
if (fill_file2(kd, kf, NULL, filed.fd_rdir, &proc,
- KERN_FILE_RDIR) == -1)
+ KERN_FILE_RDIR, pid) == -1)
return (NULL);
}
if (process.ps_tracevp) {
@@ -395,7 +407,7 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
buflen -= sizeof(struct kinfo_file2);
n++;
if (fill_file2(kd, kf, NULL, process.ps_tracevp, &proc,
- KERN_FILE_TRACE) == -1)
+ KERN_FILE_TRACE, pid) == -1)
return (NULL);
}
@@ -421,7 +433,8 @@ kvm_deadfile2_byid(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
where += sizeof(struct kinfo_file2);
buflen -= sizeof(struct kinfo_file2);
n++;
- if (fill_file2(kd, kf, &file, NULL, &proc, i) == -1)
+ if (fill_file2(kd, kf, &file, NULL, &proc, i, pid)
+ == -1)
return (NULL);
}
}
@@ -432,7 +445,7 @@ done:
static int
fill_file2(kvm_t *kd, struct kinfo_file2 *kf, struct file *fp, struct vnode *vp,
- struct proc *p, int fd)
+ struct proc *p, int fd, pid_t pid)
{
struct ucred f_cred;
@@ -532,6 +545,11 @@ fill_file2(kvm_t *kd, struct kinfo_file2 *kf, struct file *fp, struct vnode *vp,
return (-1);
}
kf->so_family = domain.dom_family;
+ if (sock.so_splice) {
+ kf->so_splice = PTRTOINT64(sock.so_splice);
+ kf->so_splicelen = sock.so_splicelen;
+ } else if (sock.so_spliceback)
+ kf->so_splicelen = -1;
if (!sock.so_pcb)
break;
switch (kf->so_family) {
@@ -547,6 +565,7 @@ fill_file2(kvm_t *kd, struct kinfo_file2 *kf, struct file *fp, struct vnode *vp,
kf->inp_laddru[0] = inpcb.inp_laddr.s_addr;
kf->inp_fport = inpcb.inp_fport;
kf->inp_faddru[0] = inpcb.inp_faddr.s_addr;
+ kf->inp_rtableid = inpcb.inp_rtableid;
break;
}
case AF_INET6: {
@@ -568,6 +587,7 @@ fill_file2(kvm_t *kd, struct kinfo_file2 *kf, struct file *fp, struct vnode *vp,
kf->inp_faddru[1] = inpcb.inp_faddr6.s6_addr32[1];
kf->inp_faddru[2] = inpcb.inp_faddr6.s6_addr32[2];
kf->inp_faddru[3] = inpcb.inp_faddr6.s6_addr32[3];
+ kf->inp_rtableid = inpcb.inp_rtableid;
break;
}
case AF_UNIX: {
@@ -621,9 +641,10 @@ fill_file2(kvm_t *kd, struct kinfo_file2 *kf, struct file *fp, struct vnode *vp,
/* per-process information for KERN_FILE_BY[PU]ID */
if (p != NULL) {
- kf->p_pid = p->p_pid;
+ kf->p_pid = pid;
kf->p_uid = p->p_ucred->cr_uid;
kf->p_gid = p->p_ucred->cr_gid;
+ kf->p_tid = p->p_pid + THREAD_PID_OFFSET;
strlcpy(kf->p_comm, p->p_comm, sizeof(kf->p_comm));
if (p->p_fd != NULL)
kf->fd_ofileflags = p->p_fd->fd_ofileflags[fd];
diff --git a/lib/libkvm/kvm_getprocs.3 b/lib/libkvm/kvm_getprocs.3
index cf1a0b69189..e2acf477b22 100644
--- a/lib/libkvm/kvm_getprocs.3
+++ b/lib/libkvm/kvm_getprocs.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: kvm_getprocs.3,v 1.16 2011/08/18 13:01:26 jmc Exp $
+.\" $OpenBSD: kvm_getprocs.3,v 1.17 2012/01/07 05:38:12 guenther Exp $
.\" $NetBSD: kvm_getprocs.3,v 1.13 2003/08/07 16:44:37 agc Exp $
.\"
.\" Copyright (c) 1992, 1993
@@ -34,16 +34,13 @@
.\"
.\" @(#)kvm_getprocs.3 8.1 (Berkeley) 6/4/93
.\"
-.Dd $Mdocdate: August 18 2011 $
+.Dd $Mdocdate: January 7 2012 $
.Dt KVM_GETPROCS 3
.Os
.Sh NAME
.Nm kvm_getprocs ,
.Nm kvm_getargv ,
-.Nm kvm_getenvv ,
-.Nm kvm_getproc2 ,
-.Nm kvm_getargv2 ,
-.Nm kvm_getenvv2
+.Nm kvm_getenvv
.Nd access user process state
.Sh SYNOPSIS
.Fd #include <sys/param.h>
@@ -55,12 +52,6 @@
.Fn kvm_getargv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
.Ft char **
.Fn kvm_getenvv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
-.Ft struct kinfo_proc *
-.Fn kvm_getproc2 "kvm_t *kd" "int op" "int arg" "size_t elemsize" "int *cnt"
-.Ft char **
-.Fn kvm_getargv2 "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
-.Ft char **
-.Fn kvm_getenvv2 "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
.Sh DESCRIPTION
.Fn kvm_getprocs
returns a (sub-)set of active processes in the kernel indicated by
@@ -172,26 +163,11 @@ function is similar to
.Fn kvm_getargv
but returns the vector of environment strings.
This data is also alterable by the process.
-.Pp
-The
-.Fn kvm_getproc2 ,
-.Fn kvm_getargv2 ,
-and
-.Fn kvm_getenvv2
-functions are obsolete equivalents for
-.Fn kvm_getprocs ,
-.Fn kvm_getargv ,
-and
-.Fn kvm_getenvv
-and have identical signatures and behavior.
.Sh RETURN VALUES
.Fn kvm_getprocs ,
.Fn kvm_getargv ,
-.Fn kvm_getenvv ,
-.Fn kvm_getproc2 ,
-.Fn kvm_getargv2 ,
and
-.Fn kvm_getenvv2
+.Fn kvm_getenvv
all return
.Dv NULL
on failure.
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 57be5c1b731..8bc0745b638 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc.c,v 1.44 2011/06/06 17:18:26 ariane Exp $ */
+/* $OpenBSD: kvm_proc.c,v 1.45 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -474,12 +474,6 @@ kvm_getargv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
}
char **
-kvm_getargv2(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
-{
- return (kvm_getargv(kd, kp, nchr));
-}
-
-char **
kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
{
struct miniproc p;
@@ -490,12 +484,6 @@ kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
return (kvm_doargv(kd, &p, nchr, ps_str_e));
}
-char **
-kvm_getenvv2(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
-{
- return (kvm_getenvv(kd, kp, nchr));
-}
-
/*
* Read from user space. The user context is given by p.
*/
diff --git a/lib/libkvm/kvm_proc2.c b/lib/libkvm/kvm_proc2.c
index 33052b3e6e8..f98c7db2ebc 100644
--- a/lib/libkvm/kvm_proc2.c
+++ b/lib/libkvm/kvm_proc2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kvm_proc2.c,v 1.8 2011/07/05 04:48:01 guenther Exp $ */
+/* $OpenBSD: kvm_proc2.c,v 1.9 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
struct vmspace vm, *vmp;
struct plimit limits, *limp;
struct pstats pstats, *ps;
- pid_t parent_pid, leader_pid;
+ pid_t process_pid, parent_pid, leader_pid;
int cnt = 0;
for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) {
@@ -136,6 +136,17 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
process.ps_cred);
return (-1);
}
+ if ((proc.p_flag & P_THREAD) == 0)
+ process_pid = proc.p_pid;
+ else {
+ if (KREAD(kd, (u_long)process.ps_mainproc, &proc2)) {
+ _kvm_err(kd, kd->program,
+ "can't read proc at %x",
+ process.ps_mainproc);
+ return (-1);
+ }
+ process_pid = proc2.p_pid;
+ }
if (KREAD(kd, (u_long)pcred.pc_ucred, &ucred)) {
_kvm_err(kd, kd->program, "can't read ucred at %x",
pcred.pc_ucred);
@@ -282,6 +293,7 @@ kvm_proclist(kvm_t *kd, int op, int arg, struct proc *p,
#undef do_copy_str
/* stuff that's too painful to generalize into the macros */
+ kp.p_pid = process_pid;
kp.p_ppid = parent_pid;
kp.p_sid = leader_pid;
if ((process.ps_flags & PS_CONTROLT) && sess.s_ttyp != NULL) {
@@ -406,10 +418,3 @@ kvm_getprocs(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
*cnt = nprocs;
return (kd->procbase);
}
-
-struct kinfo_proc *
-kvm_getproc2(kvm_t *kd, int op, int arg, size_t esize, int *cnt)
-{
- return (kvm_getprocs(kd, op, arg, esize, cnt));
-}
-
diff --git a/lib/libkvm/shlib_version b/lib/libkvm/shlib_version
index f461c533903..56246d02b24 100644
--- a/lib/libkvm/shlib_version
+++ b/lib/libkvm/shlib_version
@@ -1,2 +1,2 @@
-major=11
+major=12
minor=0
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 478ee32e2ca..9095f134113 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.210 2011/12/14 07:32:16 guenther Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.211 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1137,6 +1137,11 @@ fill_file2(struct kinfo_file2 *kf, struct file *fp, struct filedesc *fdp,
kf->so_pcb = PTRTOINT64(so->so_pcb);
kf->so_protocol = so->so_proto->pr_protocol;
kf->so_family = so->so_proto->pr_domain->dom_family;
+ if (so->so_splice) {
+ kf->so_splice = PTRTOINT64(so->so_splice);
+ kf->so_splicelen = so->so_splicelen;
+ } else if (so->so_spliceback)
+ kf->so_splicelen = -1;
if (!so->so_pcb)
break;
switch (kf->so_family) {
@@ -1148,6 +1153,7 @@ fill_file2(struct kinfo_file2 *kf, struct file *fp, struct filedesc *fdp,
kf->inp_laddru[0] = inpcb->inp_laddr.s_addr;
kf->inp_fport = inpcb->inp_fport;
kf->inp_faddru[0] = inpcb->inp_faddr.s_addr;
+ kf->inp_rtableid = inpcb->inp_rtableid;
break;
}
case AF_INET6: {
@@ -1164,6 +1170,7 @@ fill_file2(struct kinfo_file2 *kf, struct file *fp, struct filedesc *fdp,
kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1];
kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2];
kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3];
+ kf->inp_rtableid = inpcb->inp_rtableid;
break;
}
case AF_UNIX: {
@@ -1201,9 +1208,10 @@ fill_file2(struct kinfo_file2 *kf, struct file *fp, struct filedesc *fdp,
/* per-process information for KERN_FILE_BY[PU]ID */
if (pp != NULL) {
- kf->p_pid = pp->p_pid;
+ kf->p_pid = pp->p_p->ps_pid;
kf->p_uid = pp->p_ucred->cr_uid;
kf->p_gid = pp->p_ucred->cr_gid;
+ kf->p_tid = pp->p_pid + THREAD_PID_OFFSET;
strlcpy(kf->p_comm, pp->p_comm, sizeof(kf->p_comm));
}
if (fdp != NULL)
@@ -1489,6 +1497,7 @@ fill_kproc(struct proc *p, struct kinfo_proc *ki)
p, pr, s, p->p_vmspace, pr->ps_limit, p->p_stats, p->p_sigacts);
/* stuff that's too painful to generalize into the macros */
+ ki->p_pid = pr->ps_pid;
if (pr->ps_pptr)
ki->p_ppid = pr->ps_pptr->ps_pid;
if (s->s_leader)
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 43a388c265c..5a5215a312a 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.148 2011/12/14 07:32:16 guenther Exp $ */
+/* $OpenBSD: proc.h,v 1.149 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -388,6 +388,8 @@ struct proc {
#define P_EXITSIG(p) \
(((p)->p_flag & P_TRACED) ? SIGCHLD : (p)->p_exitsig)
+#define THREAD_PID_OFFSET 1000000
+
/*
* MOVE TO ucred.h?
*
@@ -421,7 +423,6 @@ struct uidinfo *uid_find(uid_t);
*/
#define PID_MAX 32766
#define NO_PID (PID_MAX+1)
-#define THREAD_PID_OFFSET 1000000
#define SESS_LEADER(pr) ((pr)->ps_session->s_leader == (pr))
#define SESSHOLD(s) ((s)->s_count++)
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index fd913e26c6d..8c2d7a730bd 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.119 2011/12/14 07:32:16 guenther Exp $ */
+/* $OpenBSD: sysctl.h,v 1.120 2012/01/07 05:38:12 guenther Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -38,16 +38,11 @@
#ifndef _SYS_SYSCTL_H_
#define _SYS_SYSCTL_H_
-/*
- * These are for the eproc structure defined below.
- */
#ifndef _KERNEL
#include <sys/proc.h> /* for SRUN, SIDL, etc */
-#include <sys/resource.h>
+#include <sys/resource.h> /* for struct loadavg */
#endif
-#include <sys/resourcevar.h> /* XXX */
-
#include <uvm/uvm_extern.h>
/*
@@ -177,7 +172,6 @@ struct ctlname {
#define KERN_WATCHDOG 64 /* node: watchdog */
#define KERN_EMUL 65 /* node: emuls */
#define KERN_PROC 66 /* struct: process entries */
-#define KERN_PROC2 KERN_PROC /* backwards compat name */
#define KERN_MAXCLUSTERS 67 /* number of mclusters */
#define KERN_EVCOUNT 68 /* node: event counters */
#define KERN_TIMECOUNTER 69 /* node: timecounter */
@@ -325,9 +319,6 @@ struct ctlname {
#define KI_NOCPU (~(u_int64_t)0)
struct kinfo_proc {
-#ifndef kinfo_proc2
-#define kinfo_proc2 kinfo_proc
-#endif
u_int64_t p_forw; /* PTR: linked run/sleep queue. */
u_int64_t p_back;
u_int64_t p_paddr; /* PTR: address of proc */
@@ -443,6 +434,8 @@ struct kinfo_proc {
u_int64_t p_rlim_rss_cur; /* RLIM_T: soft limit for rss */
u_int64_t p_cpuid; /* LONG: CPU id */
u_int64_t p_vm_map_size; /* VSIZE_T: virtual size */
+ int32_t p_tid; /* PID_T: Thread identifier. */
+ u_int32_t p_rtableid; /* U_INT: Routing table identifier. */
};
#if defined(_KERNEL) || defined(_LIBKVM)
@@ -468,7 +461,7 @@ struct kinfo_proc {
* ps - source struct pstats
* sa - source struct sigacts
* There are some members that are not handled by these macros
- * because they're too painful to generalize: p_ppid, p_sid, p_tdev,
+ * because they're too painful to generalize: p_pid, p_ppid, p_sid, p_tdev,
* p_tpgid, p_tsess, p_vm_rssize, p_u[us]time_{sec,usec}, p_cpuid
*/
@@ -490,7 +483,6 @@ do { \
(kp)->p_exitsig = (p)->p_exitsig; \
(kp)->p_flag = (p)->p_flag | (pr)->ps_flags | P_INMEM; \
\
- (kp)->p_pid = (p)->p_pid; \
(kp)->p__pgid = (pg)->pg_id; \
\
(kp)->p_uid = (uc)->cr_uid; \
@@ -596,6 +588,8 @@ do { \
} \
\
(kp)->p_cpuid = KI_NOCPU; \
+ (kp)->p_tid = (p)->p_pid + THREAD_PID_OFFSET; \
+ (kp)->p_rtableid = (pr)->ps_rtableid; \
} while (0)
#endif /* defined(_KERNEL) || defined(_LIBKVM) */
@@ -685,8 +679,14 @@ struct kinfo_file2 {
uint32_t fd_ofileflags; /* CHAR: open file flags */
uint32_t p_uid; /* UID_T: process credentials */
uint32_t p_gid; /* GID_T: process credentials */
- uint32_t __spare; /* padding */
+ uint32_t p_tid; /* PID_T: thread id */
char p_comm[KI_MAXCOMLEN];
+
+ /* more socket information */
+ uint32_t inp_rtableid; /* UINT: Routing table identifier. */
+ uint64_t so_splice; /* PTR: f_data of spliced socket */
+ int64_t so_splicelen; /* OFF_T: already spliced count or */
+ /* -1 if this is target of splice */
};
/*
diff --git a/usr.bin/fstat/fstat.1 b/usr.bin/fstat/fstat.1
index edea8c943cd..1b8cc169032 100644
--- a/usr.bin/fstat/fstat.1
+++ b/usr.bin/fstat/fstat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fstat.1,v 1.47 2011/10/02 21:46:29 jmc Exp $
+.\" $OpenBSD: fstat.1,v 1.48 2012/01/07 05:38:12 guenther Exp $
.\"
.\" Copyright (c) 1987, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)fstat.1 8.3 (Berkeley) 2/25/94
.\"
-.Dd $Mdocdate: October 2 2011 $
+.Dd $Mdocdate: January 7 2012 $
.Dt FSTAT 1
.Os
.Sh NAME
@@ -226,6 +226,8 @@ and a full duplex socket shows a double arrow
.Pp
For
.Dv AF_INET
+and
+.Dv AF_INET6
sockets,
.Nm
also attempts to print the internet address and port for the
@@ -243,6 +245,21 @@ use of the arrow
or
.Dq --> )
indicates the direction the socket connection was created.
+.Pp
+If the socket has been spliced to or from another socket (c.f.
+.Xr setsockopt 2
+and
+.Dv SO_SPLICE
+) then
+.Nm
+prints a thick arrow
+.Pf ( Dq <==> ,
+.Dq <== ,
+or
+.Dq ==> ) ,
+followed by the address and endpoint information of the other socket
+in the splice,
+if available.
.Sh PIPES
Every pipe is printed as an address which is the same for both sides of
the pipe and a state that is built of the letters
diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c
index 1e4be93d0ef..6efe3702ab1 100644
--- a/usr.bin/fstat/fstat.c
+++ b/usr.bin/fstat/fstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fstat.c,v 1.71 2011/07/09 00:45:40 henning Exp $ */
+/* $OpenBSD: fstat.c,v 1.72 2012/01/07 05:38:12 guenther Exp $ */
/*
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -73,6 +73,7 @@
#include <limits.h>
#include <nlist.h>
#include <pwd.h>
+#include <search.h>
#include <signal.h>
#include <stdio.h>
#include <stdint.h>
@@ -103,13 +104,20 @@ uid_t uid;
void fstat_dofile(struct kinfo_file2 *);
void fstat_header(void);
-void fuser_dofile(struct kinfo_file2 *);
void getinetproto(int);
void usage(void);
int getfname(char *);
void cryptotrans(struct kinfo_file2 *);
void kqueuetrans(struct kinfo_file2 *);
void pipetrans(struct kinfo_file2 *);
+struct kinfo_file2 *splice_find(char, u_int64_t);
+void splice_insert(char, u_int64_t, struct kinfo_file2 *);
+void find_splices(struct kinfo_file2 *, int);
+void print_inet_details(struct kinfo_file2 *);
+#ifdef INET6
+void print_inet6_details(struct kinfo_file2 *);
+#endif
+void print_sock_details(struct kinfo_file2 *);
void socktrans(struct kinfo_file2 *);
void systracetrans(struct kinfo_file2 *);
void vtrans(struct kinfo_file2 *);
@@ -255,6 +263,7 @@ main(int argc, char *argv[])
if ((kf = kvm_getfile2(kd, what, arg, sizeof(*kf), &cnt)) == NULL)
errx(1, "%s", kvm_geterr(kd));
+ find_splices(kf, cnt);
if (!fuser)
fstat_header();
for (kflast = &kf[cnt]; kf < kflast; ++kf) {
@@ -543,6 +552,141 @@ inet6_addrstr(struct in6_addr *p)
#endif
void
+splice_insert(char type, u_int64_t ptr, struct kinfo_file2 *data)
+{
+ ENTRY entry, *found;
+
+ if (asprintf(&entry.key, "%c%llx", type, ptr) == -1)
+ err(1, NULL);
+ entry.data = data;
+ if ((found = hsearch(entry, ENTER)) == NULL)
+ err(1, "hsearch");
+ /* if it's ambiguous, set the data to NULL */
+ if (found->data != data)
+ found->data = NULL;
+}
+
+struct kinfo_file2 *
+splice_find(char type, u_int64_t ptr)
+{
+ ENTRY entry, *found;
+ char buf[20];
+
+ snprintf(buf, sizeof(buf), "%c%llx", type, ptr);
+ entry.key = buf;
+ found = hsearch(entry, FIND);
+ return (found != NULL ? found->data : NULL);
+}
+
+void
+find_splices(struct kinfo_file2 *kf, int cnt)
+{
+ int i, created;
+
+ created = 0;
+ for (i = 0; i < cnt; i++) {
+ if (kf[i].f_type != DTYPE_SOCKET ||
+ (kf[i].so_splice == 0 && kf[i].so_splicelen != -1))
+ continue;
+ if (created++ == 0) {
+ if (hcreate(1000) == 0)
+ err(1, "hcreate");
+ }
+ splice_insert('>', kf[i].f_data, &kf[i]);
+ if (kf[i].so_splice != 0)
+ splice_insert('<', kf[i].so_splice, &kf[i]);
+ }
+}
+
+void
+print_inet_details(struct kinfo_file2 *kf)
+{
+ struct in_addr laddr, faddr;
+
+ memcpy(&laddr, kf->inp_laddru, sizeof(laddr));
+ memcpy(&faddr, kf->inp_faddru, sizeof(faddr));
+ if (kf->so_protocol == IPPROTO_TCP) {
+ printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
+ printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :
+ inet_ntoa(laddr), ntohs(kf->inp_lport));
+ if (kf->inp_fport) {
+ if (kf->so_state & SS_CONNECTOUT)
+ printf(" --> ");
+ else
+ printf(" <-- ");
+ printf("%s:%d",
+ faddr.s_addr == INADDR_ANY ? "*" :
+ inet_ntoa(faddr), ntohs(kf->inp_fport));
+ }
+ } else if (kf->so_protocol == IPPROTO_UDP) {
+ printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :
+ inet_ntoa(laddr), ntohs(kf->inp_lport));
+ if (kf->inp_fport) {
+ printf(" <-> %s:%d",
+ faddr.s_addr == INADDR_ANY ? "*" :
+ inet_ntoa(faddr), ntohs(kf->inp_fport));
+ }
+ } else if (kf->so_pcb)
+ printf(" %p", (void *)(uintptr_t)kf->so_pcb);
+}
+
+#ifdef INET6
+void
+print_inet6_details(struct kinfo_file2 *kf)
+{
+ char xaddrbuf[NI_MAXHOST + 2];
+ struct in6_addr laddr6, faddr6;
+
+ memcpy(&laddr6, kf->inp_laddru, sizeof(laddr6));
+ memcpy(&faddr6, kf->inp_faddru, sizeof(faddr6));
+ if (kf->so_protocol == IPPROTO_TCP) {
+ printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
+ snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
+ inet6_addrstr(&laddr6));
+ printf(" %s:%d",
+ IN6_IS_ADDR_UNSPECIFIED(&laddr6) ? "*" :
+ xaddrbuf, ntohs(kf->inp_lport));
+ if (kf->inp_fport) {
+ if (kf->so_state & SS_CONNECTOUT)
+ printf(" --> ");
+ else
+ printf(" <-- ");
+ snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
+ inet6_addrstr(&faddr6));
+ printf("%s:%d",
+ IN6_IS_ADDR_UNSPECIFIED(&faddr6) ? "*" :
+ xaddrbuf, ntohs(kf->inp_fport));
+ }
+ } else if (kf->so_protocol == IPPROTO_UDP) {
+ snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
+ inet6_addrstr(&laddr6));
+ printf(" %s:%d",
+ IN6_IS_ADDR_UNSPECIFIED(&laddr6) ? "*" :
+ xaddrbuf, ntohs(kf->inp_lport));
+ if (kf->inp_fport) {
+ snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
+ inet6_addrstr(&faddr6));
+ printf(" <-> %s:%d",
+ IN6_IS_ADDR_UNSPECIFIED(&faddr6) ? "*" :
+ xaddrbuf, ntohs(kf->inp_fport));
+ }
+ } else if (kf->so_pcb)
+ printf(" %p", (void *)(uintptr_t)kf->so_pcb);
+}
+#endif
+
+void
+print_sock_details(struct kinfo_file2 *kf)
+{
+ if (kf->so_family == AF_INET)
+ print_inet_details(kf);
+#ifdef INET6
+ else if (kf->so_family == AF_INET6)
+ print_inet6_details(kf);
+#endif
+}
+
+void
socktrans(struct kinfo_file2 *kf)
{
static char *stypename[] = {
@@ -555,11 +699,6 @@ socktrans(struct kinfo_file2 *kf)
};
#define STYPEMAX 5
char *stype, stypebuf[24];
- struct in_addr laddr, faddr;
-#ifdef INET6
- char xaddrbuf[NI_MAXHOST + 2];
- struct in6_addr laddr6, faddr6;
-#endif
PREFIX(kf->fd_fd);
@@ -584,72 +723,14 @@ socktrans(struct kinfo_file2 *kf)
switch (kf->so_family) {
case AF_INET:
printf("* internet %s", stype);
- memcpy(&laddr, kf->inp_laddru, sizeof(laddr));
- memcpy(&faddr, kf->inp_faddru, sizeof(faddr));
getinetproto(kf->so_protocol);
- if (kf->so_protocol == IPPROTO_TCP) {
- printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
- printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :
- inet_ntoa(laddr), ntohs(kf->inp_lport));
- if (kf->inp_fport) {
- if (kf->so_state & SS_CONNECTOUT)
- printf(" --> ");
- else
- printf(" <-- ");
- printf("%s:%d",
- faddr.s_addr == INADDR_ANY ? "*" :
- inet_ntoa(faddr), ntohs(kf->inp_fport));
- }
- } else if (kf->so_protocol == IPPROTO_UDP) {
- printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :
- inet_ntoa(laddr), ntohs(kf->inp_lport));
- if (kf->inp_fport) {
- printf(" <-> %s:%d",
- faddr.s_addr == INADDR_ANY ? "*" :
- inet_ntoa(faddr), ntohs(kf->inp_fport));
- }
- } else if (kf->so_pcb)
- printf(" %p", (void *)(uintptr_t)kf->so_pcb);
+ print_inet_details(kf);
break;
#ifdef INET6
case AF_INET6:
printf("* internet6 %s", stype);
- memcpy(&laddr6, kf->inp_laddru, sizeof(laddr6));
- memcpy(&faddr6, kf->inp_faddru, sizeof(faddr6));
getinetproto(kf->so_protocol);
- if (kf->so_protocol == IPPROTO_TCP) {
- printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
- snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
- inet6_addrstr(&laddr6));
- printf(" %s:%d",
- IN6_IS_ADDR_UNSPECIFIED(&laddr6) ? "*" :
- xaddrbuf, ntohs(kf->inp_lport));
- if (kf->inp_fport) {
- if (kf->so_state & SS_CONNECTOUT)
- printf(" --> ");
- else
- printf(" <-- ");
- snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
- inet6_addrstr(&faddr6));
- printf("%s:%d",
- IN6_IS_ADDR_UNSPECIFIED(&faddr6) ? "*" :
- xaddrbuf, ntohs(kf->inp_fport));
- }
- } else if (kf->so_protocol == IPPROTO_UDP) {
- snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
- inet6_addrstr(&laddr6));
- printf(" %s:%d",
- IN6_IS_ADDR_UNSPECIFIED(&laddr6) ? "*" :
- xaddrbuf, ntohs(kf->inp_lport));
- if (kf->inp_fport) {
- snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
- inet6_addrstr(&faddr6));
- printf(" <-> %s:%d",
- IN6_IS_ADDR_UNSPECIFIED(&faddr6) ? "*" :
- xaddrbuf, ntohs(kf->inp_fport));
- }
- } else if (kf->so_pcb)
- printf(" %p", (void *)(uintptr_t)kf->so_pcb);
+ print_inet6_details(kf);
break;
#endif
case AF_UNIX:
@@ -702,6 +783,27 @@ socktrans(struct kinfo_file2 *kf)
printf(" %d %p", kf->so_protocol,
(void *)(uintptr_t)kf->f_data);
}
+ if (kf->so_splice != 0 || kf->so_splicelen == -1) {
+ struct kinfo_file2 *from, *to;
+
+ from = splice_find('<', kf->f_data);
+ to = NULL;
+ if (kf->so_splice != 0)
+ to = splice_find('>', kf->so_splice);
+
+ if (to != NULL && from == to) {
+ printf(" <==>");
+ print_sock_details(to);
+ } else if (kf->so_splice != 0) {
+ printf(" ==>");
+ if (to != NULL)
+ print_sock_details(to);
+ } else if (kf->so_splicelen == -1) {
+ printf(" <==");
+ if (from != NULL)
+ print_sock_details(from);
+ }
+ }
if (sflg)
printf("\t%8llu %8llu",
(kf->f_rxfer + kf->f_rwfer),