psutil support for Solaris OS
Comment #1
Posted on Feb 23, 2009 by Grumpy Lion(No comment was entered for this change.)
Comment #2
Posted on Feb 23, 2009 by Quick GiraffeDo we have a Solaris OS to test against?
Comment #3
Posted on Feb 23, 2009 by Grumpy LionNo, we need to install one in a VM using Solaris x86 or find a Solaris box we can use. Or of course, someone willing to take up the porting effort, since I'm already doing OS X, Windows, and FreeBSD as it is ;)
Comment #4
Posted on Feb 24, 2009 by Quick GiraffeI know, we'd need more C coders. =) I could take the effort of installing a VM with Open Solaris and provide SSH access for you and Dave, but I'd postpone this Issue for another release other than 0.1.2.
Comment #5
Posted on Mar 9, 2009 by Quick Giraffe(No comment was entered for this change.)
Comment #6
Posted on Jun 19, 2010 by Happy MonkeyI'm closing this out for now as it's unlikely we'll find time to look into this in the near future.
Comment #7
Posted on Sep 24, 2010 by Happy Monkey(No comment was entered for this change.)
Comment #8
Posted on Jan 24, 2012 by Massive CamelI actually have working code for reading proc on Solaris 10+ and access to a lot of test Solaris servers. There are only a few things that I know of that don't work with implementation such as getting the Environment Settings from the process and CPU utilization is untested. I am unfamiliar with psutil's code base, but I be able share my implementation in the next few days. It is pure python and uses 'struct' to decode the information. I have shared a limited proc parser in Issue 247, that was recently closed as a duplicate of Issue 18.
Comment #9
Posted on Jan 24, 2012 by Happy MonkeyIdeally, the whole API should be implemented by using the doc as reference: http://code.google.com/p/psutil/wiki/Documentation. Practically speaking, I know this is a huge amount of work, therefore a partial implementation including base functionalities (system cpu/memory, process name, cpu, memory, ...) would also be good for now.
I don't have any experience with Solaris platforms, but I assume that /proc filesystem is not as rich as the one on Linux. As such, it is likely that different things must be done in C. Any resource/link talking about C/kernel development on Solaris is welcome (see what we did in http://code.google.com/p/psutil/wiki/UsefulResources).
If you need any help with grokking psutil code base just ask out.
Comment #10
Posted on Jan 24, 2012 by Grumpy LionIs /proc always available on Solaris? I might be misremembering but I thought support procfs was optional on Solaris systems or not available on all architectures. If it is available that would save us a lot of headaches dealing with C code for most metrics.
Comment #11
Posted on Jan 25, 2012 by Massive CamelI know on Solaris 10+ it is available on both Sparc and Intel architectures. A system admin can disable it, but that issue exists on linux as well. A simple set of tests during initialization could catch that though.
if platform.system() != 'SunOS': raise OSError("Sorry, only SunOS is supported")
_sunos_version = int(platform.release().split('.')[-1]) if _sunos_version < 10: raise OSError("Sorry, version %d of SunOS is not supported" % _sunos_version)
if not os.listdir('/proc'): raise OSError("Sorry procfs is not available on your system")
Comment #12
Posted on Jan 25, 2012 by Massive CamelOver the next couple of days I will see if I can take the code that I have and make it fit the psutil api. I will attach a patch when I have something to show.
Comment #13
Posted on Jan 25, 2012 by Grumpy LionExcellent, thanks. It's been a while since I worked on Solaris with any regularity and I seemed to recall not having /proc available on our systems. That should vastly simplify porting efforts and it'd be great to add Solaris as a supported platform.
Comment #14
Posted on Jan 29, 2012 by Massive CamelDroneD was released on Thursday and can make use of psutil for process management. It also has some old platform support that it provides, but I would like to remove. One of the url's below provides the full working Solaris implementation that I have had for a long time and it supports the interfaces that DroneD expects. The code is Apache 2.0 licensed and if there is any concern about that I can work with legal department at Orbitz to clear it (I can't speak for legal, but psutil's license is in our approved list). Ideally I would like to move this support to this project and just let DroneD rely on psutil.
Solaris original implementation: https://github.com/OrbitzWorldwide/droned/blob/master/droned/lib/kitt/proc/SunOS.py
How DroneD uses psutil: https://github.com/OrbitzWorldwide/droned/blob/master/droned/lib/kitt/proc/psutil_backend.py https://github.com/OrbitzWorldwide/droned/blob/master/droned/services/systemstats.py
Main Page: https://github.com/OrbitzWorldwide/droned/
Some Documentation: https://github.com/OrbitzWorldwide/droned/wiki/_pages
Comment #15
Posted on Jan 30, 2012 by Happy MonkeyMmm the implementation looks quite complicated/messy. Where does this stuff come from? https://github.com/OrbitzWorldwide/droned/blob/master/droned/lib/kitt/proc/SunOS.py#L62 Is it documented somewhere? You said this works on Solaris 10+. What about other Solaris variants? Are you willing to start writing an actual patch for integration with psutil? Once we have that we can start looking into the missing parts.
Comment #16
Posted on Jan 30, 2012 by Massive CamelNo doubt the original implementation is a mess and was done when Solaris 10 was still fairly new, also I was new to python when it was written. I haven't tested it with anything lower that Solaris 10. Yes I am planning on writing a native set of patches for psutil, I just wanted to make everyone aware of where it originally comes from.
Comment #17
Posted on Jan 30, 2012 by Happy MonkeyFrom http://en.wikipedia.org/wiki/Solaris_(operating_system)#version-history - Solaris 10 (5.10): January 31, 2005 - Solaris 11 (5.11): November 15, 2010 We should support these two only, both Sparc and Intel architectures. Let's ignore any other previous version.
Comment #18
Posted on May 27, 2012 by Massive CamelI am not quite ready to submit my Solaris support as a patch, but I am providing a link to a github repo that I am currently working on (see end of message). I have one outstanding issue that I have to rework to support the method psutil.Process.get_memory_maps
and of course I need feedback before I actually submit this as a full patch.
My code passes psutil.test
. It has feature parity with the linux implementation with one exception, which is get_connections. I cannot see an easy way to get the network connections for a given process without using DTRACE and I haven't had a whole lot of success making that work.
This code is written in cython (mostly for clarity of code) and in my opinion is pretty straightforward to read. The patch I am planning to submit in the future will contain the cython source, generated C source, and with clear instructions on how to emit the C source from the cython source.
Comment #19
Posted on May 27, 2012 by Massive CamelI was able to track down and fix the issue that was preventing psutil.Process.get_memory_maps
from working in my Solaris implementation. Would anyone like to review the code (over the next few weeks) so I can put together a complete patch?
Comment #20
Posted on May 28, 2012 by Happy MonkeyHi Justin, and congrats for the great progress.
I'm probably missing something but since most of the work is done by parsing /proc why did you decide to use Cython instead of Python? Ideally, it would be better to do this in Python as we did for Linux for better maintainability.
As for process connections, I notice you managed to implement process's get_open_files() by using /proc/PID/fd and /proc/PID/path. Are you sure /proc does not provide the necessary pieces to interface with sockets as well? My best guess is that /proc/PID/fd is supposed to contain both regular file and socket fds. As a last resort we might use the lsof parser as we're currently doing for FreeBSD: http://code.google.com/p/psutil/source/browse/tags/release-0.4.1/psutil/_psposix.py#115 ...or it that's too much trouble we can decide to drop connections support for Solaris.
Comment #21
Posted on May 28, 2012 by Massive CamelIn my opinion Cython is more aesthetically pleasing than pure C and python. While my opinion is certainly subjective I think it makes the implementation very easy to understand. A minor technical bonus is reference counting is automatically handle by Cython.
The real reason I chose Cython was all of the C only API's on Solaris such as kstat (the only way to get at kernel statics such as disk-io counters). Also alot of the proc structured files have vector pointers and I think is easier to perform the pointer arithmetic in C (I'm not even sure how I would do it with struct and python). Yes I could have used ctypes, but then code would would be even harder to understand. Lastly, I have better things to do than write in C :).
Unfortunately I didn't see a concise way get the socket connections from the proc information. Honestly I didn't spend a whole lot of time on this code (maybe 30 hours over a few months) so I may have missed something easy.I know we can get the information from dtrace, with limitations. I was kind of hoping someone would see an elegant solution to this and propose a fix. I could probably go through the netstat code on opensolaris and see how they do it. I may be able to figure that part out if I spent a few more days on it.
Comment #22
Posted on May 28, 2012 by Massive CamelOh and thanks for looking at the code, I appreciate the feedback.
Comment #23
Posted on May 28, 2012 by Massive Camelget_connections will probably take me an hour or so to add when I have the time.
reference.
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/ptools/pfiles/pfiles.c
Comment #24
Posted on May 29, 2012 by Massive CamelI just noticed the unittests. I may write one for solaris in the future as well. Currently the solaris implementation fails on get_connections (expected).
jvenus@solar:~/Projects/svn/psutil-read-only/test$ PYTHONPATH=../build/lib.solaris-2.11-i86pc -2.6 python test_memory_leaks.py test_cmdline (main.TestProcessObjectLeaks) ... ok test_create_time (main.TestProcessObjectLeaks) ... ok test_get_connections (main.TestProcessObjectLeaks) ... ERROR test_get_cpu_affinity (main.TestProcessObjectLeaks) ... skipped-ok test_get_cpu_times (main.TestProcessObjectLeaks) ... ok test_get_environ (main.TestProcessObjectLeaks) ... skipped-ok test_get_memory_info (main.TestProcessObjectLeaks) ... ok test_get_memory_maps (main.TestProcessObjectLeaks) ... ok test_get_num_threads (main.TestProcessObjectLeaks) ... ok test_get_open_files (main.TestProcessObjectLeaks) ... ok test_get_threads (main.TestProcessObjectLeaks) ... ok test_getcwd (main.TestProcessObjectLeaks) ... skipped-ok test_gids (main.TestProcessObjectLeaks) ... ok test_is_running (main.TestProcessObjectLeaks) ... ok test_name (main.TestProcessObjectLeaks) ... ok test_ppid (main.TestProcessObjectLeaks) ... ok test_resume (main.TestProcessObjectLeaks) ... skipped-ok test_status (main.TestProcessObjectLeaks) ... ok test_terminal (main.TestProcessObjectLeaks) ... ok test_uids (main.TestProcessObjectLeaks) ... ok test_username (main.TestProcessObjectLeaks) ... skipped-ok test_cpu_times (main.TestModuleFunctionsLeaks) ... ok test_disk_io_counters (main.TestModuleFunctionsLeaks) ... ok test_disk_partitions (main.TestModuleFunctionsLeaks) ... ok test_disk_usage (main.TestModuleFunctionsLeaks) ... skipped-ok test_get_pid_list (main.TestModuleFunctionsLeaks) ... ok test_get_users (main.TestModuleFunctionsLeaks) ... ok test_network_io_counters (main.TestModuleFunctionsLeaks) ... ok test_per_cpu_times (main.TestModuleFunctionsLeaks) ... ok test_phymem_usage (main.TestModuleFunctionsLeaks) ... ok test_pid_exists (main.TestModuleFunctionsLeaks) ... skipped-ok test_process_iter (main.TestModuleFunctionsLeaks) ... ok test_virtmem_usage (main.TestModuleFunctionsLeaks) ... ok
======================================================================
ERROR: test_get_connections (main.TestProcessObjectLeaks)
Traceback (most recent call last): File "/home/jvenus/Projects/svn/psutil-read-only/test/test_psutil.py", line 144, in inner return fun(self, *args, **kwargs) File "test_memory_leaks.py", line 194, in test_get_connections self.execute('get_connections', kind='all') File "test_memory_leaks.py", line 41, in execute self.call(function, *args, **kwargs) File "test_memory_leaks.py", line 97, in call obj(*args, **kwargs) File "/home/jvenus/Projects/svn/psutil-read-only/build/lib.solaris-2.11-i86pc-2.6/psutil/init.py", line 514, in get_connections return self._platform_impl.get_connections(kind) File "_psutil_solaris.pyx", line 1293, in psutil._psutil_solaris.Process.get_connections (psutil/_psutil_solaris.c:9472) AccessDenied: (pid=1864)
Ran 33 tests in 81.994s
FAILED (errors=1) jvenus@solar:~/Projects/svn/psutil-read-only/test$
Comment #25
Posted on May 29, 2012 by Happy MonkeyIndependently from how good/better Cython is, the current code base does not rely on it and introducing it as a 3th party dep or rewriting the existent code base from scratch is not an option at this point.
Please note that most of the work on Solaris is done by reading /proc. That means that, once we figure out a way to "decode" /proc fs, that can be easily done in pure python. I don't know whether the resulting Python code would be better or worse compared to Cython's, but that's not the point here (consider that none of us are fluent in Cython).
The only parts requiring C are 4 or 5 (e.g. disk/net io counters), and some of them such as disk partitions and system users are basically the same as on other UNIX platform, for which code has already been written and tested.
In summary, I would be more keen on seeing a progress in this direction: - a patch consisting in a py module and a C extension - figure out how to decode /proc fs from python and use python wherever possible - use C as last resort
Comment #26
Posted on May 30, 2012 by Happy MonkeyI've just tried to look into this directly. I think one possibility is to rewrite _update_info() and _update_status() [1] in C so that they return a python dict reflecting the original C structs. I'll keep going down this route and possibly come up with a preliminary patch.
[1] https://github.com/JustinVenus/psutil-solaris/blob/master/_psutil_solaris.pyx#L790
Comment #27
Posted on May 30, 2012 by Massive Camel@g.rodola If you want to port it from Cython to straight C I am more than happy to test it. I am almost done prototyping the get_connections in Cython as well.
Comment #28
Posted on May 30, 2012 by Happy MonkeyHow would you do that exactly? By hand or by using cython (doesn't it produce a messy C code?)? Would we still have an intermediate .py module or would it be all C? Perhaps you can show me how you would implement, say, get_process_ppid()?
In case you need it, attached is a patch which creates the base structure (py module + C extension).
- init.patch 4.75KB
Comment #29
Posted on May 30, 2012 by Massive CamelI can test your patches on my Solaris boxes. For get_connections[1], as with most interesting things about a process in Solaris the proc files only give you clues, we have to examine the address space (/proc/%(pid)d/as) for the details[2].
1) Overview get_connections
this is how we can determine that a fd is a socket.
def get_connections(self, kind='inet'):
# use fd for filedescriptor list
base = '/proc/%d/fd' % (self._pid,)
for fd in os.listdir(base):
f = os.path.join(base, fd)
stats = os.stat(f)
#S_IFMT and S_IFSOCK are defined in "sys/stat.h"
if stats.st_mode & S_IFMT != S_IFSOCK:
continue
#the file descriptor is a socket
Then we will have to make a few ioctl calls to take control of the process
and examine the address space as the following code examples show. This will get us #what port, ip, we are listening to and bread crumbs for the protocol and other side
of the connection. I am still reading over the following code to see what needs to be done at minimum to support
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libproc/common/Psyscall.c#Psyscall
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/ptools/pfiles/pfiles.c#714
2): example of examining address space https://github.com/JustinVenus/psutil-solaris/blob/master/_psutil_solaris.pyx#L1011
Comment #30
Posted on May 30, 2012 by Massive CamelI just noticed your (init.patch) patch won't work because, we cannot directly include "sys/procfs.h" for definitions because of a conflict with "pyconfig.h". Basically what happens is pyconfig.h defines _FILE_OFFSET_BITS as 64 which is incompatible with a definition that is included in "sys/procfs_old.h" and this causes a linking error. For a more complete explanation see [1].
We could do some preprocesser magic by checking if that #define is set, save it as another #define, undef the original, include "sys/procfs.h", udef yet again, and restore the original definition. It would be ugly, but should work around that issue.
1) procfs.h python fun. http://old.nabble.com/-RFA-Python--Fix-procfs.c-build-failure-on-32bit-solaris-(_FILE_OFFSET_BITS)-p30284417.html
Comment #31
Posted on May 30, 2012 by Happy MonkeyThat is why I used:
undef _FILE_OFFSET_BITS // XXX
That worked on Open Solaris 5.11 i386 (32 bit).
Comment #32
Posted on May 30, 2012 by Massive CamelI missed that, my apologies.
Comment #33
Posted on May 31, 2012 by Happy MonkeyI'm working on a patch including preliminary basic process info - the ones which can be easily extracted from /proc/PID/psinfo and /proc/PID/status. I should be able to post it later today. If that's ok with you I can commit it on a separate branch and from there we can start working on it togheter and complete the missing parts.
Comment #34
Posted on May 31, 2012 by Massive CamelSounds good to me.
Comment #35
Posted on May 31, 2012 by Happy MonkeyThe new branch is at: https://psutil.googlecode.com/svn/branches/sunos
I committed:
- r1315 (base files structure + different Process methods)
- r1316 (get_users())
- r1317 (disk_partitions())
I also gave you commit access against the repo.
I marked the missing parts with "TODO" comments here: http://code.google.com/p/psutil/source/browse/branches/sunos/psutil/_pssunos.py?spec=svn1317&r=1317
The test suite is still unstable, let's ignore the failures for now. I can go on and port the kstat* related code tomorrow. Maybe you can take a look at process connections and open files?
Comment #36
Posted on Jun 1, 2012 by Happy MonkeyFurther progress:
r1319: system CPU times r1320: system disk IO counters r1322: process uids/gids r1324: process threads r1325: process open files r1326: process cwd r1327: system virtmem
What remains to be done:
- system network io counters
- process connections
- process memory maps
- process environ
Comment #37
Posted on Jun 25, 2012 by Happy MonkeyIssue 288 has been merged into this issue.
Comment #38
Posted on Aug 17, 2012 by Happy MonkeyFurther progress:
r1515: process memory maps r1516: network IO counters r1518: system virtual memory r1519: process context switches r1520: process num fds
We're almost there. The only things missing are:
- process connections
- system swap memory
I'm having a hard time implementing the latter (swap memory) and have no clue at all about process connections at the moment. Any help is appreciated.
Comment #39
Posted on Aug 18, 2012 by Massive CamelYeah the swap usage per process was a real pain to figure out, I had to read the source for the Solaris process utils to get as far as I did. Speaking of that, did I share the cython code that implemented swap usage per process? If I didn't let me know and I will send it to you.
Justin Venus
Comment #40
Posted on Aug 18, 2012 by Happy MonkeyHi Justin, you did but what we're looking for is to emulate the output of "swap -l", which produces different results. The funny thing is that "swap" source code is available, and also pretty easy to read, nevertheless I failed to pull out the same numbers: http://code.google.com/p/psutil/source/browse/branches/sunos/psutil/_psutil_sunos.c?spec=svn1534&r=1530#209 As for now I wrote a parser for "swap -l" in order to pass tests: http://code.google.com/p/psutil/source/browse/branches/sunos/psutil/_pssunos.py?spec=svn1534&r=1531#51
As for process_connections(): netstat source code seems to be the right place where to look but it's messy as hell. Alternatively "pfiles" cmdline utility uses a different approach, but unfortunately it doesn't provide TCP connection status. I'll figure something out eventually (at least I hope :P)...
Comment #41
Posted on Dec 13, 2012 by Happy Monkey(No comment was entered for this change.)
Comment #42
Posted on Feb 27, 2013 by Helpful CatThe feature is currently being crowdfunded https://www.catincan.com/proposal/psutil/psutil-solaris-support
Comment #43
Posted on Mar 1, 2013 by Happy MonkeyThanks a lot for your contribution.
Comment #44
Posted on Mar 1, 2013 by Happy MonkeyComment deleted
Comment #45
Posted on Mar 2, 2013 by Happy MonkeyNew cset links after the SVN -> Mercurial migration:
r1315 == revision 5084c50904c7 - base files structure + different Process methods r1316 == revision cebf7c743bb4 - get_users() r1317 == revision a32cdf467dff - disk_partitions() r1319 == revision b621eb32a999 - system CPU times r1320 == revision 1db3a9d7e23e - system disk IO counters r1322 == revision 99a42f7ef404 - process uids/gids r1324 == revision 87a84972a237 - process threads r1325 == revision 9ff85cfae688 - process open files r1326 == revision 53e4513a9629 - process cwd r1327 == revision c4d712a4d5b2 - system virtmem r1515 == revision dd9408eb8e5e - process memory maps r1516 == revision 69d94ebb34d4 - network IO counters r1518 == revision 99342730b261 - system virtual memory r1519 == revision cfc634ff9207 - process context switches r1520 == revision bcc64055e3f7 - process num fds
Comment #46
Posted on Mar 16, 2013 by Happy MonkeyIssue 358 has been merged into this issue.
Comment #47
Posted on Apr 9, 2013 by Happy MonkeyIssue 363 has been merged into this issue.
Comment #48
Posted on Jun 8, 2013 by Happy MonkeyOk, it seems that aside from some minor quirks I'm going to fix soon we now finally have Solaris support. sunos branch merged back into trunk as of revision bca91a5e7264. Thanks to Justin Venus for having written this in Cython. Without that I doubt I would have been able to make it.
Comment #49
Posted on Jul 11, 2013 by Happy Monkey(No comment was entered for this change.)
Status: Fixed
Labels:
Type-Enhancement
Priority-Medium
OpSys-Solaris
Milestone-1.0.0