The Wayback Machine - https://web.archive.org/web/20201125012448/https://github.com/giampaolo/psutil/pull/1564
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

Add support for new platform (IBM i) #1564

Open
wants to merge 33 commits into
base: master
from

Conversation

@ThePrez
Copy link

@ThePrez ThePrez commented Aug 5, 2019

For reference, see lengthy discussions in #1415 and #1444. I found it eventually much more sensible to have IBM i as a completely new module than sharing a codestream with AIX.
I'll attach the test output shortly. While there is still plenty of test cases that should be cleaned up, the basic functions seem to work well. This fork has been used by several applications for nearly six months, so there is some assurance of quality.

This new module relies in an external package, but IBM will distribute the package in RPM form as to ensure that does not pose a problem.

ThePrez added 30 commits Mar 1, 2019
======================================================================
FAIL: psutil.tests.test_contracts.TestFetchAllProcesses.test_fetch_all
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/JGORZINS/psutil/psutil/tests/test_contracts.py", line 356,
in test_fetch_all
meth(ret, p)
File "/home/JGORZINS/psutil/psutil/tests/test_contracts.py", line 399,
in create_time
self.assertIsInstance(ret, float)
AssertionError: 1546917581 is not an instance of <class 'float'>
@ThePrez
Copy link
Author

@ThePrez ThePrez commented Aug 6, 2019

testOutput.txt

Here is the test output. Like I said, it isn't pretty, but if you agree to merging in the new IBM i module, I'll gladly circle around to clean up the test cases (which I haven't yet figured out how to do), perhaps with the help of @jwoehr.

Jesse Gorzinski
@ThePrez
Copy link
Author

@ThePrez ThePrez commented Jun 5, 2020

@giampaolo , would you be amenable to merging this in once we further clean up these test cases?

@giampaolo
Copy link
Owner

@giampaolo giampaolo commented Jun 5, 2020

What's the test status?

@ThePrez
Copy link
Author

@ThePrez ThePrez commented Jun 7, 2020

The test status is still in pretty sad shape (no work has been done since my posted test results, above).
If you can verify that you're ok with landing this new platform support, I'll work to clean them up further.
Thanks!

@giampaolo
Copy link
Owner

@giampaolo giampaolo commented Jun 7, 2020

Just let me have a look at the output first to have an idea of what's implemented and what is not. =)

@ThePrez
Copy link
Author

@ThePrez ThePrez commented Jun 8, 2020

@giampaolo , I've done zero work on this since the posted results on Aug 5th.

Copy link
Owner

@giampaolo giampaolo left a comment

Hello Jesse. Here's an initial review. Other than the inline comments, it looks like this platform is quite different than AIX (it has it's own py and c modules) so I suggest to add a IBMI constant in _common.py and treat it differently, and also replace os.uname().sysname != 'OS400' all over the place.

Other than that, there are some errors such as this one that need to be fixed:

  File "/QOpenSys/pkgs/lib/python3.6/site-packages/psutil-5.5.1-py3.6-os400-powerpc64.egg/psutil/_psibmi.py", line 420, in _proc_name_and_args
    return cext.proc_name_and_args(self.pid)
OSError: [Errno 14] Bad address

But let's get to tests later (there's more).

@@ -163,7 +163,10 @@
PROCFS_PATH = "/proc"

elif AIX:
from . import _psaix as _psplatform
if os.uname().sysname == 'OS400':

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

This won't work on Python 2 (no namedtuple is returned). What's the value of sys.platform? It's probably better to use that one instead.

# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if err.errno in (errno.ENOENT, errno.ESRCH):

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

You don't seem to read /proc so catching ENOENT should not be necessary

class Process(object):
"""Wrapper class around underlying C implementation."""

__slots__ = ["pid", "_name", "_ppid", "_cache", "_conn"]

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

looks like "_conn" is not used

@@ -0,0 +1,518 @@
/*
* Copyright (c) 2009, Giampaolo Rodola'
* Copyright (c) 2017, Arnon Yaari

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

Replace Arnon with your name

NULL,
0,
&pid_in_table,
1);

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

Please use 4 spaces indentation. Either this:

    int rtv = getprocs64(
        dest, 
        sizeof(struct procentry64),
        NULL,
        0,
        &pid_in_table,
        1);

...or this (max 80 chars per line):

    int rtv = getprocs64(dest,  sizeof(struct procentry64), NULL, 0, 
                         &pid_in_table, 1);
for row in cursor:
ret = row[0].timestamp()
cursor.close()
return ret

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

perhaps you should use row = next(cursor) and avoid the for loop


def pid_exists(pid):
"""Check for the existence of a unix pid."""
return pid in cext.list_pids()

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

On UNIX, it's usually enough to do this (faster):

pid_exists = _psposix.pid_exists
# support for private module import
if (NoSuchProcess is None or AccessDenied is None or
ZombieProcess is None):
raise
Comment on lines +403 to +406

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

you can get rid of this stuff

stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if PY3:
stdout, stderr = [x.decode(sys.stdout.encoding)

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

use _common.decode()

for x in (stdout, stderr)]
if "no such process" in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
procfiles = re.findall(r"(\d+): S_IFREG.*\s*.*name:(.*)\n", stdout)

This comment has been minimized.

@giampaolo

giampaolo Jul 5, 2020
Owner

You can probably use re.compile('...') and use it as a private argument of this function (faster).
Grep for "re.compile" to see what I mean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants
You can’t perform that action at this time.