procstat(1): Add TCP socket send/recv buffer size

Add TCP socket send and receive buffer size to procstat -f output.

Reviewed by:	kib, markj
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D10689
This commit is contained in:
cem 2017-05-26 22:17:44 +00:00
parent 50950a1a71
commit 4281746ee5
7 changed files with 81 additions and 11 deletions

View File

@ -6,7 +6,6 @@ FBSD_1.2 {
procstat_freefiles;
procstat_freeprocs;
procstat_get_pipe_info;
procstat_get_socket_info;
procstat_getfiles;
procstat_getprocs;
procstat_open_kvm;
@ -39,5 +38,6 @@ FBSD_1.5 {
procstat_get_pts_info;
procstat_get_sem_info;
procstat_get_shm_info;
procstat_get_socket_info;
procstat_get_vnode_info;
};

View File

@ -1497,6 +1497,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
} else
sock->inp_ppcb =
(uintptr_t)inpcb.inp_ppcb;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
@ -1510,6 +1512,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
sock->so_rcv_sb_state = s.so_rcv.sb_state;
sock->so_snd_sb_state = s.so_snd.sb_state;
sock->unp_conn = (uintptr_t)unpcb.unp_conn;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
@ -1556,17 +1560,22 @@ procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
switch(sock->dom_family) {
case AF_INET:
case AF_INET6:
if (sock->proto == IPPROTO_TCP)
if (sock->proto == IPPROTO_TCP) {
sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb;
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
}
break;
case AF_UNIX:
if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) {
sock->so_rcv_sb_state =
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
sock->so_snd_sb_state =
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
sock->unp_conn =
kif->kf_un.kf_sock.kf_sock_unpconn;
sock->so_rcv_sb_state =
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
sock->so_snd_sb_state =
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
sock->unp_conn =
kif->kf_un.kf_sock.kf_sock_unpconn;
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
}
break;
default:

View File

@ -157,6 +157,8 @@ struct sockstat {
struct sockaddr_storage sa_peer; /* Peer address. */
int type;
char dname[32];
unsigned int sendq;
unsigned int recvq;
};
STAILQ_HEAD(filestat_list, filestat);

View File

@ -60,12 +60,29 @@ struct freebsd11_shmstat {
uint16_t mode;
};
struct freebsd11_sockstat {
uint64_t inp_ppcb;
uint64_t so_addr;
uint64_t so_pcb;
uint64_t unp_conn;
int dom_family;
int proto;
int so_rcv_sb_state;
int so_snd_sb_state;
struct sockaddr_storage sa_local; /* Socket address. */
struct sockaddr_storage sa_peer; /* Peer address. */
int type;
char dname[32];
};
int freebsd11_procstat_get_pts_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf);
int freebsd11_procstat_get_sem_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf);
int freebsd11_procstat_get_shm_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf);
int freebsd11_procstat_get_socket_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf);
int freebsd11_procstat_get_vnode_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf);
@ -115,6 +132,31 @@ freebsd11_procstat_get_shm_info(struct procstat *procstat,
return (0);
}
int
freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
struct freebsd11_sockstat *sock_compat, char *errbuf)
{
struct sockstat sock;
int r;
r = procstat_get_socket_info(procstat, fst, &sock, errbuf);
if (r != 0)
return (r);
sock_compat->inp_ppcb = sock.inp_ppcb;
sock_compat->so_addr = sock.so_addr;
sock_compat->so_pcb = sock.so_pcb;
sock_compat->unp_conn = sock.unp_conn;
sock_compat->dom_family = sock.dom_family;
sock_compat->proto = sock.proto;
sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state;
sock_compat->so_snd_sb_state = sock.so_snd_sb_state;
sock_compat->sa_local = sock.sa_local;
sock_compat->sa_peer = sock.sa_peer;
sock_compat->type = sock.type;
memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname));
return (0);
}
int
freebsd11_procstat_get_vnode_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf)
@ -138,6 +180,8 @@ freebsd11_procstat_get_vnode_info(struct procstat *procstat,
}
__sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2);
__sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info,
FBSD_1.2);
__sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info,
FBSD_1.2);
__sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3);

View File

@ -359,6 +359,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
inpcb = (struct inpcb *)(so->so_pcb);
kif->kf_un.kf_sock.kf_sock_inpcb =
(uintptr_t)inpcb->inp_ppcb;
kif->kf_un.kf_sock.kf_sock_sendq =
sbused(&so->so_snd);
kif->kf_un.kf_sock.kf_sock_recvq =
sbused(&so->so_rcv);
}
}
break;
@ -372,6 +376,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
so->so_rcv.sb_state;
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
so->so_snd.sb_state;
kif->kf_un.kf_sock.kf_sock_sendq =
sbused(&so->so_snd);
kif->kf_un.kf_sock.kf_sock_recvq =
sbused(&so->so_rcv);
}
}
break;

View File

@ -344,7 +344,8 @@ struct kinfo_file {
int64_t kf_offset; /* Seek location. */
union {
struct {
uint32_t kf_spareint;
/* Sendq size */
uint32_t kf_sock_sendq;
/* Socket domain. */
int kf_sock_domain0;
/* Socket type. */
@ -365,8 +366,8 @@ struct kinfo_file {
uint16_t kf_sock_snd_sb_state;
/* Receive buffer state. */
uint16_t kf_sock_rcv_sb_state;
/* Round to 64 bit alignment. */
uint32_t kf_sock_pad0;
/* Recvq size. */
uint32_t kf_sock_recvq;
} kf_sock;
struct {
/* Vnode type. */

View File

@ -534,6 +534,12 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp)
xo_emit("{:protocol/%-3s/%s} ",
protocol_to_string(sock.dom_family,
sock.type, sock.proto));
if (sock.proto == IPPROTO_TCP ||
sock.proto == IPPROTO_SCTP ||
sock.type == SOCK_STREAM) {
xo_emit("{:sendq/%u} ", sock.sendq);
xo_emit("{:recvq/%u} ", sock.recvq);
}
/*
* While generally we like to print two addresses,
* local and peer, for sockets, it turns out to be