tools: tcptop: Get command name from BPF code. (#3760)
Before this commit, command name was taken from PID using /proc/PID/comm.
But this method was not reliable as it does not work all the time.
So, this commit takes command name from BPF code using bpf_get_current_comm()
helper like it is done for biotop.
Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
diff --git a/tools/tcptop.py b/tools/tcptop.py
index 76c91af..c8bde8f 100755
--- a/tools/tcptop.py
+++ b/tools/tcptop.py
@@ -90,6 +90,7 @@
struct ipv4_key_t {
u32 pid;
+ char name[TASK_COMM_LEN];
u32 saddr;
u32 daddr;
u16 lport;
@@ -102,6 +103,7 @@
unsigned __int128 saddr;
unsigned __int128 daddr;
u32 pid;
+ char name[TASK_COMM_LEN];
u16 lport;
u16 dport;
u64 __pad__;
@@ -125,6 +127,7 @@
if (family == AF_INET) {
struct ipv4_key_t ipv4_key = {.pid = pid};
+ bpf_get_current_comm(&ipv4_key.name, sizeof(ipv4_key.name));
ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr;
ipv4_key.daddr = sk->__sk_common.skc_daddr;
ipv4_key.lport = sk->__sk_common.skc_num;
@@ -134,6 +137,7 @@
} else if (family == AF_INET6) {
struct ipv6_key_t ipv6_key = {.pid = pid};
+ bpf_get_current_comm(&ipv6_key.name, sizeof(ipv6_key.name));
bpf_probe_read_kernel(&ipv6_key.saddr, sizeof(ipv6_key.saddr),
&sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read_kernel(&ipv6_key.daddr, sizeof(ipv6_key.daddr),
@@ -173,6 +177,7 @@
if (family == AF_INET) {
struct ipv4_key_t ipv4_key = {.pid = pid};
+ bpf_get_current_comm(&ipv4_key.name, sizeof(ipv4_key.name));
ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr;
ipv4_key.daddr = sk->__sk_common.skc_daddr;
ipv4_key.lport = sk->__sk_common.skc_num;
@@ -182,6 +187,7 @@
} else if (family == AF_INET6) {
struct ipv6_key_t ipv6_key = {.pid = pid};
+ bpf_get_current_comm(&ipv6_key.name, sizeof(ipv6_key.name));
bpf_probe_read_kernel(&ipv6_key.saddr, sizeof(ipv6_key.saddr),
&sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read_kernel(&ipv6_key.daddr, sizeof(ipv6_key.daddr),
@@ -216,17 +222,11 @@
if args.ebpf:
exit()
-TCPSessionKey = namedtuple('TCPSession', ['pid', 'laddr', 'lport', 'daddr', 'dport'])
-
-def pid_to_comm(pid):
- try:
- comm = open("/proc/%d/comm" % pid, "r").read().rstrip()
- return comm
- except IOError:
- return str(pid)
+TCPSessionKey = namedtuple('TCPSession', ['pid', 'name', 'laddr', 'lport', 'daddr', 'dport'])
def get_ipv4_session_key(k):
return TCPSessionKey(pid=k.pid,
+ name=k.name,
laddr=inet_ntop(AF_INET, pack("I", k.saddr)),
lport=k.lport,
daddr=inet_ntop(AF_INET, pack("I", k.daddr)),
@@ -234,6 +234,7 @@
def get_ipv6_session_key(k):
return TCPSessionKey(pid=k.pid,
+ name=k.name,
laddr=inet_ntop(AF_INET6, k.saddr),
lport=k.lport,
daddr=inet_ntop(AF_INET6, k.daddr),
@@ -288,7 +289,7 @@
key=lambda kv: sum(kv[1]),
reverse=True):
print("%-6d %-12.12s %-21s %-21s %6d %6d" % (k.pid,
- pid_to_comm(k.pid),
+ k.name,
k.laddr + ":" + str(k.lport),
k.daddr + ":" + str(k.dport),
int(recv_bytes / 1024), int(send_bytes / 1024)))
@@ -315,7 +316,7 @@
key=lambda kv: sum(kv[1]),
reverse=True):
print("%-6d %-12.12s %-32s %-32s %6d %6d" % (k.pid,
- pid_to_comm(k.pid),
+ k.name,
k.laddr + ":" + str(k.lport),
k.daddr + ":" + str(k.dport),
int(recv_bytes / 1024), int(send_bytes / 1024)))