Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RHEL 5.3 net_if_stats OSError #797

Closed
ajvilleg opened this issue Mar 17, 2016 · 19 comments
Closed

RHEL 5.3 net_if_stats OSError #797

ajvilleg opened this issue Mar 17, 2016 · 19 comments
Labels

Comments

@ajvilleg
Copy link

I am referring to the Google Groups post here: https://groups.google.com/forum/#!topic/psutil/Ld4Z00y1-DE

I have tested with psutil 3.1.1 and 3.4.2. The trace below is with psutil 3.1.1.

As requested, I inserted some printf()'s in the code, here's the result:

$ sudo /usr/local/bin/python
Python 2.7.9 (default, Aug 10 2015, 20:17:05) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import psutil
>>> psutil.net_if_stats()
DEBUG0
DEBUG0.1
DEBUG1
DEBUG2
DEBUG3
DEBUG4
DEBUG5
DEBUG5.2.1
DEBUG5.3.1
DEBUG8
DEBUG9
DEBUG10
DEBUG11
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/psutil/__init__.py", line 1798, in net_if_stats
    return _psplatform.net_if_stats()
  File "/usr/local/lib/python2.7/site-packages/psutil/_pslinux.py", line 609, in net_if_stats
    isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 22] Invalid argument
>>> quit()
$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.3 (Tikanga)

So execution goes into psutil_net_if_stats, goes inside:

    // duplex and speed
    memset(&ethcmd, 0, sizeof ethcmd);
    ethcmd.cmd = ETHTOOL_GSET;
    ifr.ifr_data = (caddr_t)&ethcmd;
    ret = ioctl(sock, SIOCETHTOOL, &ifr);

    printf("DEBUG5\n");

    if (ret != -1) {
        printf("DEBUG5.1.1\n");
        duplex = ethcmd.duplex;
        speed = ethcmd.speed;
        printf("DEBUG5.1.2\n");
    }
    else {
        printf("DEBUG5.2.1\n");
        if (errno == EOPNOTSUPP) {
            printf("DEBUG5.2.2\n");
            // we typically get here in case of wi-fi cards
            duplex = DUPLEX_UNKNOWN;
            speed = 0;
            printf("DEBUG5.2.3\n");
        }
        else {
            printf("DEBUG5.3.1\n");
            goto error;
        }
    }

Goes to error:

error:
    printf("DEBUG8\n");
    Py_XDECREF(py_is_up);
    printf("DEBUG9\n");
    if (sock != 0)
        close(sock);
    printf("DEBUG10\n");
    PyErr_SetFromErrno(PyExc_OSError);
    printf("DEBUG11\n");
    return NULL;
}

Returns NULL to _pslinux.py at isup, duplex, speed, mtu = cext.net_if_stats(name)

def net_if_stats():
    """Get NIC stats (isup, duplex, speed, mtu)."""
    duplex_map = {cext.DUPLEX_FULL: NIC_DUPLEX_FULL,
                  cext.DUPLEX_HALF: NIC_DUPLEX_HALF,
                  cext.DUPLEX_UNKNOWN: NIC_DUPLEX_UNKNOWN}
    names = net_io_counters().keys()
    ret = {}
    print "DEBUG0"
    for name in names:
        print "DEBUG0.1"
        isup, duplex, speed, mtu = cext.net_if_stats(name)
        print "DEBUG0.2"
        duplex = duplex_map[duplex]
        ret[name] = _common.snicstats(isup, duplex, speed, mtu)
    return ret

Please let me know if you would like me to try something else. Thanks!

@wiggin15
Copy link
Collaborator

I can confirm this on RHEL 5.6.

root@host-ci019 (Redhat 5.6) ➜    python
Python 2.7.8 (default, Dec  3 2015, 15:23:36)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import psutil
>>> psutil.net_if_stats()
  File "<stdin>", line 1, in <module>
  File "/root/psutil/psutil/__init__.py", line 1831, in net_if_stats
    return _psplatform.net_if_stats()
  File "/root/psutil/psutil/_pslinux.py", line 667, in net_if_stats
    isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 22] Invalid argument

The ioctl SIOCETHTOOL (cmd ETHTOOL_GSET) returns errno 22 EINVAL.

ethtool fails too

root@host-ci019 (Redhat 5.6) ➜    ethtool -S eth0
no stats available

I think the driver or kernel or device don't support this IOCTL but I'm not sure.

@giampaolo
Copy link
Owner

Does ethtool fails also if run as root?
Il 29/mar/2016 22:43, "wiggin15" [email protected] ha scritto:

I can confirm this on RHEL 5.6.

root@host-ci019 (Redhat 5.6) ➜ python
Python 2.7.8 (default, Dec 3 2015, 15:23:36)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

import psutil
psutil.net_if_stats()
File "", line 1, in
File "/root/psutil/psutil/init.py", line 1831, in net_if_stats
return _psplatform.net_if_stats()
File "/root/psutil/psutil/_pslinux.py", line 667, in net_if_stats
isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 22] Invalid argument

The ioctl SIOCETHTOOL (cmd ETHTOOL_GSET) returns errno 22 EINVAL.

ethtool fails too

root@host-ci019 (Redhat 5.6) ➜ ethtool -S eth0
no stats available

I think the driver or kernel or device don't support this IOCTL but I'm
not sure.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#797 (comment)

@wiggin15
Copy link
Collaborator

Yes, I run it as root.
RedHat have a KB article about this: https://access.redhat.com/solutions/322353 (may require registration or subscription). It says ...ethtool queries device and driver, for some drivers/hardware combinations not every ethtool option will be valid and therefore returned message will be "no stats available" or "Operation not supported".
Other posts are saying something similar about ethtool, e.g. http://alt.os.linux.slackware.narkive.com/YCzDanP8 (Not all drivers are supported.). I couldn't find anything about the ioctl/EINVAL but this is an ethtool ioctl...
If the device doesn't support the GSET command, I suggest adding check for EINVAL in the same if where we check for EOPNOTSUPP and return DUPLEX_UNKNOWN and speed = 0

@giampaolo
Copy link
Owner

OK fixed. Can you confirm it works?

@wiggin15
Copy link
Collaborator

Yes, the latest code works for me. Thanks

@jakirkham
Copy link

I'm still running into this error with Scientific Linux 6.3. 😕

@giampaolo
Copy link
Owner

Does it still fail with EINVAL? Can you try to debug the problem by using printf()s?
The problem should occur in one of the following lines:

@giampaolo
Copy link
Owner

To build / try it yourself: git clone the repo, make changes, run make install, try the changes.

@giampaolo giampaolo reopened this Jul 12, 2016
@jakirkham
Copy link

Thanks for the quick reply.

Does it still fail with EINVAL?

So, I'm using 4.3.0 (though I have tried 4.2.0), which both seem to have this commit ( 12c7a20 ).

Can you try to debug the problem by using printf()s? The problem should occur in one of the following lines

Sure. Let me give that a try.

@jakirkham
Copy link

In attempting to build it, I ran into test failures. Though I think the test failures may be related to the original problem. I applied this diff on top of this commit ( d539e58 ) in master.

diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c
index 19fd14b..d543483 100644
--- a/psutil/_psutil_linux.c
+++ b/psutil/_psutil_linux.c
@@ -497,7 +497,9 @@ psutil_net_if_stats(PyObject* self, PyObject* args) {
     strncpy(ifr.ifr_name, nic_name, sizeof(ifr.ifr_name));

     // is up?
+    printf("DEBUG 0\n");
     ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
+    printf("DEBUG 1\n");
     if (ret == -1)
         goto error;
     if ((ifr.ifr_flags & IFF_UP) != 0)
@@ -507,7 +509,9 @@ psutil_net_if_stats(PyObject* self, PyObject* args) {
     Py_INCREF(py_is_up);

     // MTU
+    printf("DEBUG 2\n");
     ret = ioctl(sock, SIOCGIFMTU, &ifr);
+    printf("DEBUG 3\n");
     if (ret == -1)
         goto error;
     mtu = ifr.ifr_mtu;

...and got these test results.

======================================================================
ERROR: test_ifconfig (test_misc.TestScripts)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_misc.py", line 407, in test_ifconfig
    self.assert_stdout('ifconfig.py')
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_misc.py", line 347, in assert_stdout
    out = sh(sys.executable + ' ' + exe).strip()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/__init__.py", line 257, in sh
    raise RuntimeError(stderr)
RuntimeError: Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/scripts/ifconfig.py", line 80, in <module>
    main()
  File "/groups/dudman/home/kirkhamj/psutil/scripts/ifconfig.py", line 59, in main
    stats = psutil.net_if_stats()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/__init__.py", line 1971, in net_if_stats
    return _psplatform.net_if_stats()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/_pslinux.py", line 791, in net_if_stats
    isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 1] Operation not permitted


======================================================================
ERROR: test_disk_usage (test_posix.TestSystemAPIs)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_posix.py", line 330, in test_disk_usage
    total, used, free, percent = df(part.device)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_posix.py", line 320, in df
    total = int(fields[1]) * 1024
IndexError: list index out of range

======================================================================
ERROR: test_disk_usage (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 2061, in test_disk_usage
    os.mkdir(funny_directory)
OSError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_proc_cmdline (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 2008, in test_proc_cmdline
    self.copy_file(self.test_executable, funny_executable)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1975, in copy_file
    with open(dst, 'wb') as output:
IOError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_proc_cwd (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 2022, in test_proc_cwd
    os.mkdir(funny_directory)
OSError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_proc_exe (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1981, in test_proc_exe
    self.copy_file(self.test_executable, funny_executable)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1975, in copy_file
    with open(dst, 'wb') as output:
IOError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_proc_name (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1995, in test_proc_name
    self.copy_file(self.test_executable, funny_executable)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1975, in copy_file
    with open(dst, 'wb') as output:
IOError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_proc_open_files (test_process.TestNonUnicode)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 2034, in test_proc_open_files
    with open(funny_file, 'wb'):
IOError: [Errno 5] Input/output error: '/groups/dudman/home/kirkhamj/tmp/tmpCFjVnp/\xc0\x80'

======================================================================
ERROR: test_net_if_stats (test_linux.TestSystemNetwork)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_linux.py", line 339, in test_net_if_stats
    for name, stats in psutil.net_if_stats().items():
  File "/groups/dudman/home/kirkhamj/psutil/psutil/__init__.py", line 1971, in net_if_stats
    return _psplatform.net_if_stats()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/_pslinux.py", line 791, in net_if_stats
    isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 1] Operation not permitted

======================================================================
ERROR: test_net_if_stats (test_system.TestSystemAPIs)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_system.py", line 620, in test_net_if_stats
    nics = psutil.net_if_stats()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/__init__.py", line 1971, in net_if_stats
    return _psplatform.net_if_stats()
  File "/groups/dudman/home/kirkhamj/psutil/psutil/_pslinux.py", line 791, in net_if_stats
    isup, duplex, speed, mtu = cext.net_if_stats(name)
OSError: [Errno 1] Operation not permitted

======================================================================
FAIL: test_connections_unix (test_process.TestProcess)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/__init__.py", line 486, in wrapper
    return fun(*args, **kwargs)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1067, in test_connections_unix
    check(SOCK_STREAM)
  File "/groups/dudman/home/kirkhamj/psutil/psutil/tests/test_process.py", line 1058, in check
    self.assertEqual(conn.fd, sock.fileno())
AssertionError: 7 != 5

----------------------------------------------------------------------
Ran 299 tests in 8.694s

FAILED (failures=1, errors=10, skipped=93)
make: *** [test] Error 1

@giampaolo
Copy link
Owner

So, the error is different (Operation not permitted instead of EINVAL). Also, it seems you didn't get any printf(), meaning you probably didn't recompile or the psutil version you're using is not the one you edited but the one you installed, or I don't know.
Permission error is weird and unfortunately we can't really do anything about that except maybe raising psutil.AccessDenied instead of OSError.

@giampaolo
Copy link
Owner

As for the unicode related failures, those are different and would probably deserve a separate ticket. It looks like a problem with your system encoding (what is it?). The test fails but it doesn't mean psutil is broken in that regard. psutil would probably break with UnicodeDecode error if you try to pass or handle a non-unicode string via th APIs dealing with (e.g. disk_usage()) or returning a string (e.g. Process.name()), but that's the correct behavior and the fix should be changing the system (or python) encoding, not changing psutil. Or more probably the unicode tests, which should be skipped. It would be interesting to see what happens with python 3 instead of python 2, but even in that case I expect Python not being able to handle the non-ASCII strings and fail with UnicodeDecode/Encode error.

@jakirkham
Copy link

So, the error is different (Operation not permitted instead of EINVAL).

I see. Sorry. I can open a new issue if that would be preferable.

Also, it seems you didn't get any printf(), meaning you probably didn't recompile or the psutil version you're using is not the one you edited but the one you installed, or I don't know.

So, I did get the print statements, but the log was a bit long. I saw them for test_net_if_stats (test_system.TestSystemAPIs) and test_net_if_stats (test_linux.TestSystemNetwork). In both cases, I saw all 4 print statements, which agrees with your statement that this is a different problem.

Permission error is weird and unfortunately we can't really do anything about that except maybe raising psutil.AccessDenied instead of OSError.

Yeah, that seems reasonable.

@giampaolo
Copy link
Owner

I see. Sorry. I can open a new issue if that would be preferable.

Yes please. I will think about whether it's the case to turn that OSError into AccessDenied. With a ticket it'll be more likely I won't forget about it.

@jakirkham
Copy link

In regards to the Unicode errors, I wasn't really worried about those on a first pass. Though it could be some Python 2 oddities for sure. It appears that LANG=en_US.UTF-8 is set in my environment.

@jakirkham
Copy link

Do you know what is going on with the test_connections_unix failure at the end?

@jakirkham
Copy link

I see. Sorry. I can open a new issue if that would be preferable.

Yes please. I will think about whether it's the case to turn that OSError into AccessDenied. With a ticket it'll be more likely I won't forget about it.

Opened this issue ( #860 ).

@giampaolo
Copy link
Owner

Do you know what is going on with the test_connections_unix failure at the end?

Mmmm no. Does it happen all the time? If it does then I would say it's a bug.

@giampaolo
Copy link
Owner

After re-reading this it seems the original issue is fixed (here 12c7a20) and the new one is OSError EACCES, which is "legitimate".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants