From cf9d1cd9045e4d73ecd2d7308183d254081bc9b3 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Mon, 16 Jul 2018 00:10:03 +0200 Subject: [PATCH] fix #1279: catch and skip ENODEV in net_if_stat() --- HISTORY.rst | 1 + docs/index.rst | 8 ++++---- psutil/_psbsd.py | 18 ++++++++++++------ psutil/_pslinux.py | 14 ++++++++++---- psutil/_psosx.py | 18 ++++++++++++------ psutil/tests/test_system.py | 10 ++++++++++ 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 67f967eda..a5382fbcf 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -18,6 +18,7 @@ XXXX-XX-XX task_for_pid() syscall. AccessDenied is now raised instead. - 1278_: [macOS] Process.threads() incorrectly return microseconds instead of seconds. (patch by Nikhil Marathe) +- 1279_: [Linux, macOS, BSD] net_if_stats() may return ENODEV. 5.4.6 ===== diff --git a/docs/index.rst b/docs/index.rst index af207702a..d17d2c657 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1880,11 +1880,11 @@ Process class (OpenBSD) "laddr" and "raddr" fields for UNIX sockets are always set to "". This is a limitation of the OS. - .. versionchanged:: 5.3.0 : "laddr" and "raddr" are named tuples. + .. note:: + (AIX) :class:`psutil.AccessDenied` is always raised unless running + as root (lsof does the same). - .. note:: - (AIX) :class:`psutil.AccessDenied` is always raised unless running - as root (lsof does the same). + .. versionchanged:: 5.3.0 : "laddr" and "raddr" are named tuples. .. method:: is_running() diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 83f38d55e..7f4bcb6de 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -345,12 +345,18 @@ def net_if_stats(): names = net_io_counters().keys() ret = {} for name in names: - mtu = cext_posix.net_if_mtu(name) - isup = cext_posix.net_if_flags(name) - duplex, speed = cext_posix.net_if_duplex_speed(name) - if hasattr(_common, 'NicDuplex'): - duplex = _common.NicDuplex(duplex) - ret[name] = _common.snicstats(isup, duplex, speed, mtu) + try: + mtu = cext_posix.net_if_mtu(name) + isup = cext_posix.net_if_flags(name) + duplex, speed = cext_posix.net_if_duplex_speed(name) + except OSError as err: + # https://github.com/giampaolo/psutil/issues/1279 + if err.errno != errno.ENODEV: + raise + else: + if hasattr(_common, 'NicDuplex'): + duplex = _common.NicDuplex(duplex) + ret[name] = _common.snicstats(isup, duplex, speed, mtu) return ret diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index b197dba33..85ffe66a5 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1002,10 +1002,16 @@ def net_if_stats(): names = net_io_counters().keys() ret = {} for name in names: - mtu = cext_posix.net_if_mtu(name) - isup = cext_posix.net_if_flags(name) - duplex, speed = cext.net_if_duplex_speed(name) - ret[name] = _common.snicstats(isup, duplex_map[duplex], speed, mtu) + try: + mtu = cext_posix.net_if_mtu(name) + isup = cext_posix.net_if_flags(name) + duplex, speed = cext.net_if_duplex_speed(name) + except OSError as err: + # https://github.com/giampaolo/psutil/issues/1279 + if err.errno != errno.ENODEV: + raise + else: + ret[name] = _common.snicstats(isup, duplex_map[duplex], speed, mtu) return ret diff --git a/psutil/_psosx.py b/psutil/_psosx.py index 6c77dc691..d059449af 100644 --- a/psutil/_psosx.py +++ b/psutil/_psosx.py @@ -402,12 +402,18 @@ def net_if_stats(): names = net_io_counters().keys() ret = {} for name in names: - mtu = cext_posix.net_if_mtu(name) - isup = cext_posix.net_if_flags(name) - duplex, speed = cext_posix.net_if_duplex_speed(name) - if hasattr(_common, 'NicDuplex'): - duplex = _common.NicDuplex(duplex) - ret[name] = _common.snicstats(isup, duplex, speed, mtu) + try: + mtu = cext_posix.net_if_mtu(name) + isup = cext_posix.net_if_flags(name) + duplex, speed = cext_posix.net_if_duplex_speed(name) + except OSError as err: + # https://github.com/giampaolo/psutil/issues/1279 + if err.errno != errno.ENODEV: + raise + else: + if hasattr(_common, 'NicDuplex'): + duplex = _common.NicDuplex(duplex) + ret[name] = _common.snicstats(isup, duplex, speed, mtu) return ret diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index 694a7a3b6..18cbb5d8b 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -671,6 +671,16 @@ def test_net_if_stats(self): self.assertGreaterEqual(speed, 0) self.assertGreaterEqual(mtu, 0) + @unittest.skipIf(not (LINUX or BSD or MACOS), + "LINUX or BSD or MACOS specific") + def test_net_if_stats_enodev(self): + # See: https://github.com/giampaolo/psutil/issues/1279 + with mock.patch('psutil._psutil_posix.net_if_mtu', + side_effect=OSError(errno.ENODEV, "")) as m: + ret = psutil.net_if_stats() + self.assertEqual(ret, {}) + assert m.called + @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'), '/proc/diskstats not available on this linux version') @unittest.skipIf(APPVEYOR and psutil.disk_io_counters() is None,