Darren Reed wrote:
<snip>
Any ideas ?
You could use dtrace to trace fork/exec calls and create an array
indexed on pid that stashes the execname...
But that presumes that the process is created after you start the dtrace
script.
This is nice workaround and sufficiently fits my purpose. Sample output
(this is a TCP connection inside a tunnel, BTW):
ssh (pid 101603) called connect()
ssh (pid 101603) called connect()
ssh (101603) [timer]: src: 192.168.0.1:36382 dst: 192.168.0.2:22
ssh (101603) [timer]: src: 192.168.0.1:36382 dst: 192.168.0.2:22
ssh (101603) [timer]: src: 192.168.0.1:36382 dst: 192.168.0.2:22
It should probably print some retransmission data and timing information
as well for serious debugging.
Still I've kinda expected to see one of the networking gurus to jump in
and edify me with something like 'this is trivial - just go see this
structure and this pointer and that pointer ... and here's your proc_t
pointer' :)
v.
Anyway, here's the updated script:
#!/usr/sbin/dtrace -Cs
/*
* Get connections/processes which are being hurt by TCP retransmissions.
*
* NOTE: The probes need to be installed before the processes call
* listen(2)/connect(2) otherwise execnames will not be printed.
*
* Vladimir Kotal, 2009
*/
#pragma D option quiet
/* from usr/src/uts/common/inet/ipclassifier.h */
#define conn_tcp conn_proto_priv.cp_tcp
/* Associative array which keeps pid -> execname mapping */
string procs[int];
/* capture the pids of processes calling listen()/connect() */
syscall::connect:entry,
syscall::listen:entry
{
printf("%s (pid %d) called %s()\n", execname, pid, probefunc);
procs[pid] = execname;
}
/*
* Use hard-coded list of functions which can do
* BUMP_MIB(&tcps->tcps_mib, tcpRetransSegs);
*/
fbt:ip:tcp_timer:entry
{
self->tcp = ((conn_t *)arg0)->conn_tcp;
self->cause = "timer";
}
fbt:ip:tcp_input_data:entry
{
self->tcp = ((conn_t *)arg0)->conn_tcp;
self->cause = "input_data";
}
fbt:ip:tcp_ss_rexmit:entry
{
self->tcp = (tcp_t *)arg0;
self->cause = "ss_rexmit";
}
fbt:ip:tcp_sack_rxmit:entry
{
self->tcp = (tcp_t *)arg0;
self->cause = "sack_rxmit";
}
/* Free the per-thread data */
fbt:ip:tcp_timer:return,
fbt:ip:tcp_input_data:return,
fbt:ip:tcp_ss_rexmit:return,
fbt:ip:tcp_sack_rxmit:return
/self->tcp/
{
self->tcp = 0;
self->cause = 0;
}
/* TCP retransmission event */
mib:ip::tcpRetransSegs
/self->tcp != 0/
{
/* useful tcp_t members:
* ipha_t *tcp_ipha;
* ip6_t *tcp_ip6h;
* tcpha_t *tcp_tcpha;
*/
/* use backpointer from tcp_t to conn_t to get more info */
this->family = self->tcp->tcp_connp->conn_family;
this->pid = self->tcp->tcp_connp->conn_cpid;
/* src port */
this->lport = ntohs(self->tcp->tcp_tcpha->tha_lport);
/* dst port */
this->fport = ntohs(self->tcp->tcp_tcpha->tha_fport);
/* src addr */
this->laddr = inet_ntop(this->family,
(void *)&self->tcp->tcp_ipha->ipha_src);
/* dst addr */
this->faddr = inet_ntop(this->family,
(void *)&self->tcp->tcp_ipha->ipha_dst);
/* XXX does not work (even for conn_latch* members) */
this->suffix = self->tcp->tcp_connp->conn_policy != NULL ?
" [IPsec!]" : "";
/* print the data */
/* XXX add some timeval info */
printf("%s (%d) [%s]: src: %s:%d dst: %s:%d%s\n",
procs[this->pid] != 0 ? procs[this->pid] : "N/A",
this->pid, self->cause,
this->laddr, this->lport,
this->faddr, this->fport,
this->suffix);
}
_______________________________________________
networking-discuss mailing list
[email protected]