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
API for process arguments and environment #1654
Conversation
Thanks for starting this contribution! I think this will be a great addition. I'm not sure why I decided it was out of scope earlier, perhaps because of the Windows implementation needing to dig into process memory, something I wasn't about to attempt based on a few snippets in a Stack Overflow answer. I like the addition and the new proposed API looks reasonable (I've tagged @mprins for review to offer an opinion on the API as well.) Some general thoughts after a brief look at the API:
With regard to using code from Jenkins. I want to respect the intent of the MIT license which requires the copyright notice to accompany "copies" or "substantial portions". I hand-wave that at OSHI by referring to the "Contributors", which credits authors via the git history. But that will show up as your commit, not the original author. That said, I don't think it's an issue for the code I see so far, only the parsing routine looks "copied" and that's pretty much the only way to do it. I think I've seen similar C code in the JDK's ProcessHandle implementation. Would be nice to give attribution to the original author in a comment, though. For the AIX port, do you have access to an AIX machine? I got access to a server at Polarhome when I did the AIX port here, but it's been down for several months so I have no means to develop or test code there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some specific code suggestions in addition to/clarifying my comments above.
oshi-core/src/main/java/oshi/software/os/linux/LinuxOSProcess.java
Outdated
Show resolved
Hide resolved
oshi-core/src/main/java/oshi/software/os/linux/LinuxOSProcess.java
Outdated
Show resolved
Hide resolved
oshi-core/src/main/java/oshi/software/os/linux/LinuxOSProcess.java
Outdated
Show resolved
Hide resolved
oshi-core/src/test/java/oshi/software/os/OperatingSystemTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't be too hard to get program arguments on OpenBSD, not sure about program environment, either one may need elevated user privileges for security reasons
e2e55ed
to
2e84731
Compare
I went ahead and cleaned up the API, Linux implementation, some utils, and did the macOS implementation (we already were fetching the bytes, just needed to put them in a map). I'm still uncomfortable with the Windows implementation(s) as they all involve API functions which are stated may be removed in future versions of Windows, or are unreliable involving race conditions. And I think require running as administrator. Are you going to try to put in the Solaris and AIX ports? |
Good News! I got the Windows version working. As a bonus, the same memory that provides the environment pointer also gets us CWD strings (that we previously didn't support) and Command Line strings (without the overhead of WMI).
Output:
Still a work in progress as I haven't handled the IsX64/IsWow checks, but this definitely looks doable. |
Still needs handling of isX86/isWow
This looks like it's coming along nicely! I'll try to keep helping to chip away at this as I have time. The use of I added a FreeBSD implementation for OSHI. I tested it on a 64-bit FreeBSD system running in a 64-bit Java process and inspecting both 64-bit and 32-bit processes. I think the OpenBSD implementation for OSHI will be similar modulo differences in the For AIX and Solaris, I still think the easiest path forward is to copy the implementation from Jenkins (with proper attribution, of course). I have an illumos box to test on, but unfortunately I don't have an AIX box. On a side note, I don't like how the existing AIX and Solaris implementation in OSHI invokes Similarly, I don't like how the existing FreeBSD implementation in OSHI invokes I noticed that Java 9+ has Another question: Should we try to preserve the order of the environment variable entries by using |
I have an account on a Polarhome AIX server that I'm happy to share the login for. It's an older version but should be sufficient for this work. Unfortunately the drive failed and it's been down since March. Hoping it comes up soon!
There are key differences in access available to a non-root user. I chose the That doesn't mean I wouldn't love improved code, of course... it's just something I would prefer users of those OS's provide. My goals when porting to other OS's have been "provide the information and don't crash" without too much time spent on performance optimization. See also #1366 discussing exactly what you're talking about for AIX.
I think I'd like to keep them separate for now, so this PR doesn't become overly broad, and breaking changes are more easily found and isolated to a single commit. We certainly can target the same release, and we can design the implementations to be overlapping to ease transition later.
But it's also missing a lot. I seriously considered just using that code in the java11 branch but there were too many gaps. By the time I account for all the fallbacks it just adds to code bloat. Sure, it's sufficient if you want fewer bits of information, but then... the users themselves have the ability to use the I've used the JDK code as inspiration for JNA application of the same underlying code, though, so I don't think we're missing too much. Longer term (actually mid-term now that JDK17 is EA) I plan on a whole new OSHI artifact built from the ground up leveraging lessons learned. While the current version tries to provide pretty much everything to everyone, the new version will be more limited in scope (CPU, Memory, Processes to start, with community-driven additions after that), use FFI instead of JNA, and put performance at a premium.
Entirely reasonable and I'll update the ParseUtil methods to do that as part of my next Windows commit. I realized that need just now when trying to efficiently figure out how to conditionally remove the first environment variable which in my Windows tests produces the string "=::=::" (empty key, and value "::=::" in the map. Other code I've seen checks for any of several special characters in the first key/value pair and it'd be nice to just check one.
Alternately, I can look at the implementation, understand it, and write it myself. That's what I did with the Linux parsing routines and I think mine are slightly more efficient (less object creation, not that a few nanoseconds will matter). Really the key thing to know is "where is this information stored". Not that I particularly want to avoid copying/attribution, happy to do that if it's truly a drop-in-place, but I'm guessing there's going to be enough tweaking to call it original/inspired by rather than derivative. |
While I can't speak to AIX, the Solaris legacy is alive and well in the illumos community. While my company has switched from illumos to Linux and left the illumos community, I still have access to (somewhat dated) illumos boxes. And when Jenkins tried to drop Solaris-based OS support, members of the illumos community (working at several different companies) showed up to ask that it be kept. (Many of them use Jenkins to build illumos.) Those same members of the illumos community are also working with the OpenJDK community to keep illumos support alive and well in OpenJDK. My point is that demand for illumos support still exists. In a hypothetical future where Jenkins used OSHI, you'd inherit that installed user base.
That is perfectly understandable. But my eventual goal is "get Jenkins out of the process business" without causing regressions for any existing Jenkins users. And Jenkins already uses
A more explicit error handling and exception system might also be worth considering, if you haven't considered it already. Jenkins still supports Java 8, but the project will probably drop support for Java 8 sometime in the next year or so and start requiring Java 11. Jenkins has relatively simple needs: it needs to be able to list processes (including descendants) and to get arguments and environment variables. A slimmer artifact would increase the likelihood that the Jenkins core team would accept a move to OSHI. Out of curiosity, were you planning on replacing JNA with JNR? |
# Conflicts: # oshi-core/src/main/java/oshi/software/os/unix/freebsd/FreeBsdOSProcess.java # oshi-core/src/main/java/oshi/software/os/unix/openbsd/OpenBsdOSProcess.java # oshi-core/src/main/java/oshi/util/ParseUtil.java # oshi-core/src/test/java/oshi/util/ParseUtilTest.java
AIX and Solaris done. Have no way to test AIX but the implementation matches Solaris so I'm confident it will work. Any chance you can test Solaris yourself, @basil? |
OK, so the Solaris code works fine on the owning process but fails gloriously on various permissions errors since I haven't bothered to check any return codes. And I'm going to test a more efficient way of reading the bytes. |
17c2d3f
to
85871f8
Compare
Status report: Solaris code is coming along nicely and is almost in its final state. Still need to figure out something going on with the pointer sizes. They don't always seem to match Native.POINTER_SIZE (e.g., under sudo I seem to get 4-byte offset values). I'm not sure if it's JVM bitness (does sudo run a 32-bit java?) or process data model. I think I can just do the math (evnp-argv)/(argc+1) to back into it, though. After I get solaris working I'll do the same updates for AIX and see if there's anywhere I can reduce duplication. |
Ready for final review. I plan to cut a 5.8.0 release this weekend. |
Fixes #369. Posting this draft for initial feedback on the API and the overall strategy. The Linux implementation is shamelessly copied from the (MIT-licensed) code in Jenkins core. If this approach of moving code from Jenkins core into this project is deemed suitable, I'll look into moving over the Jenkins implementations for macOS, AIX, and Solaris and writing new implementations for the BSDs.