From 3ad5827b2d00ca229e01fcec4e842764c4538159 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 28 Oct 2022 15:12:11 +0200 Subject: [PATCH] hack/podmansnoop Add a script to measure the execution times of podman, crun, run and conmon. It's a trimmed down version of the exitsnoop tool and intended to guide us in future performance optimizations. The below output was generated when running `podman run --net=host docker.io/library/alpine:latest true` ``` podman (snoop) $ sudo ./hack/podmansnoop PCOMM PID PPID TID AGE(ms) conmon 51580 51569 51580 1.67 conmon 51583 51569 51583 3.53 crun 51591 51590 51591 18.28 crun 51593 51569 51593 2.48 conmon 51606 51594 51606 0.85 crun 51608 51594 51608 2.50 podman 51594 51590 51594 176.27 conmon 51590 1950 51590 214.78 podman 51569 40964 51569 431.36 ``` In the future, it would be helpful to add the arguments of the commands. `execsnoop` can reveal them quite nicely but I did not manage to merge the two scripts due to time constraints. Signed-off-by: Valentin Rothberg --- hack/podmansnoop | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100755 hack/podmansnoop diff --git a/hack/podmansnoop b/hack/podmansnoop new file mode 100755 index 0000000000..c0b485be1c --- /dev/null +++ b/hack/podmansnoop @@ -0,0 +1,98 @@ +#!/usr/bin/env python +from __future__ import print_function + +# Based on the `exitsnoop` scripts at https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py + +import argparse +import os +import platform +import re +import signal +import sys + +from bcc import BPF +from datetime import datetime +from time import strftime + +bpf_src = """ +#include +#include + +#define ARGSIZE 128 + +struct data_t { + u64 start_time; + u64 exit_time; + u32 pid; + u32 tid; + u32 ppid; + u32 sig_info; + char task[TASK_COMM_LEN]; + char argv[ARGSIZE]; +}; + +BPF_PERF_OUTPUT(events); + +TRACEPOINT_PROBE(sched, sched_process_exit) +{ + struct task_struct *task = (typeof(task))bpf_get_current_task(); + if (task->pid != task->tgid) { return 0; } + + struct data_t data = {}; + + data.start_time = task->start_time, + data.exit_time = bpf_ktime_get_ns(), + data.pid = task->tgid, + data.tid = task->pid, + data.ppid = task->real_parent->tgid, + data.sig_info = task->exit_code & 0xFF, + bpf_get_current_comm(&data.task, sizeof(data.task)); + + events.perf_submit(args, &data, sizeof(data)); + return 0; +} +""" + +def _print_header(): + print("%-16s %-7s %-7s %-7s %-7s" % + ("PCOMM", "PID", "PPID", "TID", "AGE(ms)")) + +buffer = None + +def _print_event(cpu, data, size): # callback + """Print the exit event.""" + global buffer + e = buffer["events"].event(data) + + task = e.task.decode() + if task == "3": + # For absolutely unknown reasons, 'crun' appears as '3'. + task = "crun" + + if task not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]: + return + + age = (e.exit_time - e.start_time) / 1e6 + print("%-16s %-7d %-7d %-7d %-7.2f " % + (task, e.pid, e.ppid, e.tid, age), end="") + print() + +def snoop(bpf, event_handler): + bpf["events"].open_perf_buffer(event_handler) + while True: + bpf.perf_buffer_poll() + +def main(): + global buffer + try: + buffer = BPF(text=bpf_src) + _print_header() + snoop(buffer, _print_event) + except KeyboardInterrupt: + print() + sys.exit() + + return 0 + +if __name__ == '__main__': + main()