diff options
author | Robb Manes <rmanes@redhat.com> | 2015-09-11 17:31:21 -0400 |
---|---|---|
committer | Adam Stokes <adam.stokes@ubuntu.com> | 2015-09-29 14:55:04 -0400 |
commit | 131f2ab9dc5a45fb74e1a0fb30c9819c4c9f9ffe (patch) | |
tree | 5b46467d3d39cf130ffb544eae834496b3364720 | |
parent | 26ad415d122a8964b344afc39429ff432005a452 (diff) | |
download | sos-131f2ab9dc5a45fb74e1a0fb30c9819c4c9f9ffe.tar.gz |
[networking] gather per-namespace ip and ethtool data
As more applications are beginning to use namespaces, notably OpenStack
and container-based platforms, capturing namespace data is becoming
essential.
This patch alters the networking plugin so that it is namespace aware,
collecting commands such as:
$ ip address show
$ ip route
$ iptables-save
For each individual namespace, along with per-device ethtool
information for any devices that exist in said namespaces.
Closes #642
Signed-off-by: Robb Manes <rmanes@redhat.com>
Signed-off-by: Adam Stokes <adam.stokes@ubuntu.com>
-rw-r--r-- | sos/plugins/networking.py | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/sos/plugins/networking.py b/sos/plugins/networking.py index eed4c293..45a4c02b 100644 --- a/sos/plugins/networking.py +++ b/sos/plugins/networking.py @@ -56,6 +56,37 @@ class Networking(Plugin): out[iface] = True return out + def get_ip_netns(self, ip_netns_file): + """Returns a list for which items are namespaces in the output of + ip netns stored in the ip_netns_file. + """ + out = [] + try: + ip_netns_out = open(ip_netns_file).read() + except: + return out + for line in ip_netns_out.splitlines(): + # If there's no namespaces, no need to continue + if line.startswith("Object \"netns\" is unknown") \ + or line.isspace() \ + or line[:1].isspace(): + return out + out.append(line) + return out + + def get_netns_devs(self, namespace): + """Returns a list for which items are devices that exist within + the provided namespace. + """ + ip_link_result = self.call_ext_prog("ip netns exec " + namespace + + " ip -o link") + dev_list = [] + if ip_link_result['status'] == 0: + for eth in self.get_eth_interfaces(ip_link_result['output']): + dev = eth.replace('@NONE', '') + dev_list.append(dev) + return dev_list + def collect_iptable(self, tablename): """ When running the iptables command, it unfortunately auto-loads the modules before trying to get output. Some people explicitly @@ -122,7 +153,6 @@ class Networking(Plugin): "ip maddr show", "ip neigh show", "ip neigh show nud noarp", - "ip netns", "biosdevname -d", "tc -s qdisc show", "iptables -vnxL", @@ -189,9 +219,12 @@ class Networking(Plugin): self.add_cmd_output("%s '%s'" % (nmcli_dev_details_cmd, dev)) + # Get ethtool output for every device that does not exist in a + # namespace. ip_link_result = self.call_ext_prog("ip -o link") if ip_link_result['status'] == 0: - for eth in self.get_eth_interfaces(ip_link_result['output']): + for dev in self.get_eth_interfaces(ip_link_result['output']): + eth = dev.replace('@NONE', '') self.add_cmd_output([ "ethtool "+eth, "ethtool -d "+eth, @@ -220,6 +253,30 @@ class Networking(Plugin): if self.get_option("traceroute"): self.add_cmd_output("/bin/traceroute -n %s" % self.trace_host) + # Capture additional data from namespaces; each command is run + # per-namespace. + ip_netns_file = self.get_cmd_output_now("ip netns") + cmd_prefix = "ip netns exec " + if ip_netns_file: + for namespace in self.get_ip_netns(ip_netns_file): + self.add_cmd_output([ + cmd_prefix + namespace + " ip address show", + cmd_prefix + namespace + " ip route show table all", + cmd_prefix + namespace + " iptables-save" + ]) + + # Devices that exist in a namespace use less ethtool + # parameters. Run this per namespace. + for namespace in self.get_ip_netns(ip_netns_file): + for eth in self.get_netns_devs(namespace): + ns_cmd_prefix = cmd_prefix + namespace + " " + self.add_cmd_output([ + ns_cmd_prefix + "ethtool " + eth, + ns_cmd_prefix + "ethtool -i " + eth, + ns_cmd_prefix + "ethtool -k " + eth, + ns_cmd_prefix + "ethtool -S " + eth + ]) + return def postproc(self): |