diff options
author | Jose Castillo <jose.mfcastillo@gmail.com> | 2020-01-06 14:56:49 +0100 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2020-02-14 16:40:42 +0000 |
commit | b4f6003b7501d312bf384ae918055f4b7ef3bc9b (patch) | |
tree | 2b96f46b304ba5367190f1417a6d8a17422b5c66 | |
parent | e86e511604062175d8bac1b99f0f84a348385969 (diff) | |
download | sos-b4f6003b7501d312bf384ae918055f4b7ef3bc9b.tar.gz |
[ebpf] Add new plugin for eBPF commands
This plugin groups all bpftool commands from
plugins kernel and networking, and adds a new
one command 'bpftool cgroup tree', as requested
by rhbz#1787586.
Resolves: #1907
Related: RHBZ#1787586
Signed-off-by: Jose Castillo <jose.mfcastillo@gmail.com>
-rw-r--r-- | sos/plugins/ebpf.py | 78 | ||||
-rw-r--r-- | sos/plugins/kernel.py | 35 | ||||
-rw-r--r-- | sos/plugins/networking.py | 5 |
3 files changed, 78 insertions, 40 deletions
diff --git a/sos/plugins/ebpf.py b/sos/plugins/ebpf.py new file mode 100644 index 00000000..0659407a --- /dev/null +++ b/sos/plugins/ebpf.py @@ -0,0 +1,78 @@ +# This file is part of the sos project: https://github.com/sosreport/sos +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# version 2 of the GNU General Public License. +# +# See the LICENSE file in the source distribution for further information. + +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin +import json + + +class eBPF(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): + + plugin_name = 'ebpf' + profiles = ('system', 'kernel', 'network') + + def get_bpftool_prog_ids(self, prog_json): + out = [] + try: + prog_data = json.loads(prog_json) + except Exception as e: + self._log_info("Could not parse bpftool prog list as JSON: %s" % e) + return out + for item in range(len(prog_data)): + if "id" in prog_data[item]: + out.append(prog_data[item]["id"]) + return out + + def get_bpftool_map_ids(self, map_json): + out = [] + try: + map_data = json.loads(map_json) + except Exception as e: + self._log_info("Could not parse bpftool map list as JSON: %s" % e) + return out + for item in range(len(map_data)): + if "id" in map_data[item]: + out.append(map_data[item]["id"]) + return out + + def setup(self): + # collect list of eBPF programs and maps and their dumps + progs = self.collect_cmd_output("bpftool -j prog list") + for prog_id in self.get_bpftool_prog_ids(progs['output']): + for dumpcmd in ["xlated", "jited"]: + self.add_cmd_output("bpftool prog dump %s id %s" % + (dumpcmd, prog_id)) + maps = self.collect_cmd_output("bpftool -j map list") + for map_id in self.get_bpftool_map_ids(maps['output']): + self.add_cmd_output("bpftool map dump id %s" % map_id) + + # Iterate over all cgroups and list all attached programs + self.add_cmd_output("bpftool cgroup tree") + + # collect list of bpf program attachments in the kernel + # networking subsystem + self.add_cmd_output("bpftool net list") + + # Capture list of bpf program attachments from namespaces + ip_netns = self.exec_cmd("ip netns") + cmd_prefix = "ip netns exec " + if ip_netns['status'] == 0: + out_ns = [] + for line in ip_netns['output'].splitlines(): + # If there's no namespaces, no need to continue + if line.startswith("Object \"netns\" is unknown") \ + or line.isspace() \ + or line[:1].isspace(): + continue + out_ns.append(line.partition(' ')[0]) + for namespace in out_ns: + ns_cmd_prefix = cmd_prefix + namespace + " " + self.add_cmd_output([ + ns_cmd_prefix + "bpftool net list", + ]) + +# vim: set et ts=4 sw=4 : diff --git a/sos/plugins/kernel.py b/sos/plugins/kernel.py index 8224e5c0..98f905ed 100644 --- a/sos/plugins/kernel.py +++ b/sos/plugins/kernel.py @@ -9,7 +9,6 @@ from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin import os import glob -import json class Kernel(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): @@ -27,30 +26,6 @@ class Kernel(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): ("trace", "gather /sys/kernel/debug/tracing/trace file", "slow", False) ] - def get_bpftool_prog_ids(self, prog_file): - out = [] - try: - prog_data = json.load(open(prog_file)) - except Exception as e: - self._log_info("Could not parse bpftool prog list as JSON: %s" % e) - return out - for item in range(len(prog_data)): - if "id" in prog_data[item]: - out.append(prog_data[item]["id"]) - return out - - def get_bpftool_map_ids(self, map_file): - out = [] - try: - map_data = json.load(open(map_file)) - except Exception as e: - self._log_info("Could not parse bpftool map list as JSON: %s" % e) - return out - for item in range(len(map_data)): - if "id" in map_data[item]: - out.append(map_data[item]["id"]) - return out - def setup(self): # compat self.add_cmd_output("uname -a", root_symlink="uname") @@ -143,14 +118,4 @@ class Kernel(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin): if not self.get_option("trace"): self.add_forbidden_path("/sys/kernel/debug/tracing/trace") - # collect list of eBPF programs and maps and their dumps - prog_file = self.exec_cmd("bpftool -j prog list") - for prog_id in self.get_bpftool_prog_ids(prog_file): - for dumpcmd in ["xlated", "jited"]: - self.add_cmd_output("bpftool prog dump %s id %s" % - (dumpcmd, prog_id)) - map_file = self.exec_cmd("bpftool -j map list") - for map_id in self.get_bpftool_map_ids(map_file): - self.add_cmd_output("bpftool map dump id %s" % map_id) - # vim: set et ts=4 sw=4 : diff --git a/sos/plugins/networking.py b/sos/plugins/networking.py index 1cda0f03..4e1382e5 100644 --- a/sos/plugins/networking.py +++ b/sos/plugins/networking.py @@ -199,10 +199,6 @@ class Networking(Plugin): if self.get_option("traceroute"): self.add_cmd_output("/bin/traceroute -n %s" % self.trace_host) - # collect list of bpf program attachments in the kernel - # networking subsystem - self.add_cmd_output("bpftool net list") - # Capture additional data from namespaces; each command is run # per-namespace. ip_netns = self.exec_cmd("ip netns") @@ -246,7 +242,6 @@ class Networking(Plugin): ns_cmd_prefix + "netstat %s -neopa" % self.ns_wide, ns_cmd_prefix + "netstat -s", ns_cmd_prefix + "netstat %s -agn" % self.ns_wide, - ns_cmd_prefix + "bpftool net list", ]) ss_cmd = ns_cmd_prefix + "ss -peaonmi" |