aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Manes <rmanes@redhat.com>2015-09-11 17:31:21 -0400
committerAdam Stokes <adam.stokes@ubuntu.com>2015-09-29 14:55:04 -0400
commit131f2ab9dc5a45fb74e1a0fb30c9819c4c9f9ffe (patch)
tree5b46467d3d39cf130ffb544eae834496b3364720
parent26ad415d122a8964b344afc39429ff432005a452 (diff)
downloadsos-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.py61
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):