RFR (M/L): 8131168: Refactor ProcessHandleImpl_*.c and add implememtation for AIX
Roger Riggs
Roger.Riggs at Oracle.com
Mon Jul 20 14:56:42 UTC 2015
Hi Volker,
yes, press ahead.
On the _unix topic, I think the most platforms depends on when/how/what
you count.
I was following the prior pattern that counted OS X as being mostly
common with Linux
and Oracle Linux as a Redhat derivative. That counts at least as 2 I think.
I'd be interested in other folks views on the usefulness of
partial/truncated info from the API.
If the values are so weak they are only useful for logging then that's
not good enough.
Perhaps the truncated information should be presented from a different
method
from ProcessHandle.Info object to be able to reflect its poor quality.
Thanks, Roger
On 7/20/2015 10:46 AM, Volker Simonis wrote:
> Hi Roger,
>
> thanks for looking at the webrev. Please find my comments inline:
>
> On Mon, Jul 20, 2015 at 4:01 PM, Roger Riggs <Roger.Riggs at oracle.com> wrote:
>> Hi Volker,
>>
>> yes, generally, the approach is an improvement and provides a clearer
>> model of os specific variations.
>>
>> More comments inline...
>>
>>
>> On 7/17/2015 2:28 PM, Volker Simonis wrote:
>>> Hi,
>>>
>>> I worked on refactoring the native ProcessHandleImpl implementation to
>>> enable more code sharing and make it easier to add support for new
>>> platforms (e.g. AIX) and I think I had a pretty nice version running. But
>>> unfortunately I've just realized that the recent changes to
>>> ProcessHandleImpl (i.e. "8078099: (process) ProcessHandle should uniquely
>>> identify processes" and "8078108: (process) ProcessHandle.isAlive should
>>> be
>>> robust") have been massive so I have to start over to merge all my changes
>>> with the new version.
>>>
>>> But before doing that I just wanted to post my current changes which
>>> cleanly apply to the repo before 8078099 and ask for your opinion:
>>>
>>> http://cr.openjdk.java.net/~simonis/webrevs/2015/8131168.v1/
>>>
>>> Here's a summary (taken from ProcesHandleImpl_unix.c) of what I've
>>> actually
>>> done (if the output appears scrambled in you mail better read it in the
>>> webrev
>>>
>>> http://cr.openjdk.java.net/~simonis/webrevs/2015/8131168.v1/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c.udiff.html
>>> ):
>>>
>>> /**
>>> * This file contains the implementation of the native ProcessHandleImpl
>>> * functions which are common to all Unix variants.
>>> *
>>> * The currently supported Unix variants are Solaris, Linux, MaxOS X and
>>> AIX.
>>> * The various similarities and differences between these systems make it
>>> hard
>>> * to find a clear boundary between platform specific and shared code.
>>> *
>>> * In order to ease code sharing between the pltforms while still keeping
>>> the
>>> * code as clean as possible (i.e. free of preprocessor macros) we use
>>> the
>>> * following source code layout (remember that ProcessHandleImpl_unix.c
>>> will
>>> * be compiled on EVERY Unix platform while ProcessHandleImpl_<os>.c will
>>> be
>>> * only compiled on the specific OS):
>>> *
>>> * - all the JNI wrappers for the ProcessHandleImpl functions go into
>>> this
>>> file
>>> * - if their implementation is common on ALL the supported Unix
>>> platforms
>>> it
>>> * goes right into the JNI wrappers
>>> * - if the whole function or substantial parts are platform dependent,
>>> the
>>> * implementation goes into os_<function_name> functions in
>>> * ProcessHandleImpl_<os>.c
>>> * - if at least two platforms implement an os_<function_name> function
>>> in
>>> the
>>> * same way, this implementation is factored out into
>>> unix_<function_name>,
>>> * placed into this file and called from the corresponding
>>> os_<function_name>
>>> * function.
>>> * - For convenience, all the os_ and unix_ functions are declared in
>>> * ProcessHandleImpl_unix.h which is included into every
>>> * ProcessHandleImpl_<os>.c file.
>>> *
>>> * Example 1:
>>> * ----------
>>> * The implementation of
>>> Java_java_lang_ProcessHandleImpl_00024Info_initIDs()
>>> * is the same on all platforms except on Linux where it initilizes one
>>> * additional field. So we place the implementation right into
>>> * Java_java_lang_ProcessHandleImpl_00024Info_initIDs() but add call to
>>> * os_init() at the end of the function which is empty on all platforms
>>> * except Linux where it performs the additionally initializations.
>>> *
>>> * Example 2:
>>> * ----------
>>> * The implementation of Java_java_lang_ProcessHandleImpl_00024Info_info0
>>> is
>>> * the same on Solaris and AIX but different on Linux and MacOSX. We
>>> therefore
>>> * simply call the two helpers os_getStatInfo() and os_getCmdlineInfo().
>>> The
>>> * Linux and MaxOS X versions of these functions (in the corresponding
>>> files
>>> * ProcessHandleImpl_linux.c and ProcessHandleImpl_macosx.c) directly
>>> contain
>>> * the platform specific implementations while the Solaris and AIX
>>> * implementations simply call back to unix_getStatInfo() and
>>> * unix_getCmdlineInfo() which are implemented right in this file.
>>> *
>>> * The term "same implementation" is still a question of interpretation.
>>> It
>>> my
>>> * be acceptable to have a few ifdef'ed lines if that allows the sharing
>>> of
>>> a
>>> * huge function. On the other hand, if the platform specific code in a
>>> shared
>>> * function grows over a certain limit, it may be better to refactor that
>>> * functionality into corresponding, platform-specific os_ functions.
>>> */
>>>
>>> This resulted in the new file ProcessHandleImpl_linux.c which now only
>>> contains Linux-only code which was previously in ifdefed for Linux in
>>> ProcessHandleImpl_linux.c. The advantage is that we now have only one
>>> version of:
>>>
>>> Java_java_lang_ProcessHandleImpl_00024Info_initIDs
>>> unix_fillArgArray
>>> unix_uidToUser
>>>
>>> and on version of
>>>
>>> unix_getChildren
>>>
>>> which is shared by Solaris, Linux and AIX and one version of
>>>
>>> unix_getStatInfo
>>> unix_getCmdlineInfo
>>>
>>> which are shared by Solaris and Linux.
>>>
>>> Additionally I've added the AIX port following the new schema and I've
>>> slightly improved the Solaris port to use the information from
>>> psinfo.pr_psargs for reporting at least the first 80 characters of the
>>> command line arguments. arg[0] from psinfo.pr_psargs is also used as the
>>> "command()" string in the case where "/proc/%d/path/a.out" isn't readable.
>>> This helps to report a command string for all the processes we do not own,
>>> because in that case, "/proc/%d/path/a.out" isn't readable. By the way,
>>> using args[0] as a fall-back for cmd beeing null also helps on MacOS X for
>>> processes we don't own. Finally I've also done some test improvements.
>> My bias was toward omitting information that was incomplete or not usable
>> programatically.
>> If the commandline is truncated then it is pretty useless to a program, the
>> same with
>> the executable command. If the application has to try to guess what's
>> missing and how
>> to use what is present then it should be omitted from the API. If there is
>> a user present
>> then they can use 'ps' or 'tasklist' and interpret the partial information.
>>
> But 'ps' is limited to 80 characters for arguments and command line as
> well on Solaris as far as I know. Moreover, on AIX I haven't found
> something better than this for the command line at all. Anyway we have
> to live with the fact that this information is extremely platform
> dependent. The least common divisor is surely the PID but for this API
> I prefer to expose "as much as possible" for a given platform.
>
> I suspect that once this API is out there in the world, people will
> use it for all kind of stuff like monitoring or logging and I'd rather
> prefer to see a truncated command line in a log file instad of just
> seeing a plain PID. So usefull/useless depends pretty much on the use
> case :)
>
>> The focus should be on an API that can be used to control/manage a set of
>> applications
>> the run together, usually under the same userid or with root privileges.
>>
>> Comments on the diffs:
>>
>> ProcessHandle.java:
>> - The notes should probably be use @implNote (though I disagree with
>> providing truncated information)
>>
> Didn't knew that one but I'll use it. Thanks for the hint.
>> ProcessHandleImpl_unix:
>> - I would not have expected to find the Solaris and AIX implementations of
>> getStatInfo
>> and getCmdlineInfo here; but perhaps it depends on how one considers the
>> lineage of the real unix.
>> Since the more common platforms are Linux, Redhat, etc I would keep those
>> versions in the
>> ProcessHandleImpl_unix common file.
>>
> As I wrote in the summary - I don't think the _unix file should
> contain the implementations of the most prominent Unix platform but
> rather the implementations shared between most platforms. If a
> function implementation is only being used on Linux I think it is
> reasonable to put it into a _linux file.
>
> A while ago we discussed if the 'unix' directory should be named
> 'unix' or 'posix' or whatsoever and ended up with 'unix'. I think
> that's a good decision because it honours the fact that there is no
> single, true, genuine Unix variant. The 'unix' directory is a
> pragmatic approach to share "common" Unix code with "common" in the
> sense of "supported by at least two or more Unix variants". At least
> that was my understanding.
>
> I'll start to merge in your new changes into my schema and post a new
> webrev once I'm done.
>
> Thanks once again for your comments,
> Volker
>
>> Thanks, Roger
>>
>>
>>
>>
>>> I have tested all my changes on Linux/amd64, Linux/ppc64, MacOS X, Solaris
>>> and AIX.
>>>
>>> I'd be happy to forward port my changes to the newest head version if you
>>> generally agree with my approach (and give me a short time frame where you
>>> promise not to do any massive changes :)
>>>
>>> What do you think?
>>>
>>> Thank you and best regards,
>>> Volker
>>
More information about the core-libs-dev
mailing list