the implementation I originally provided does not in fact solve the issue!
the attach protocol initiation "handhake" requires that the "attacher" (the caller of this code) and the "attachee"(the target JVM to be "attached" to) *must* share a "/tmp" in common in order to rendezvous on the "attach" socket (created in the /tmp filesystem).
"attacher" and "attachee" JVM processes are guaranteed to share a common "/tmp" directory/filesystem when thy occupy the same "mount namespace", this is the environment in which "peers" exist, and the attach
handshake (initiated by the attacher) can use "/tmp" to establish the socket connection with the attachee.
with the advent of "containers" (implemented in Linux via various namespaces, e.g.: pid & mount) another "attacher" and "attachee" relationship exists, that of "attacher" (ancestor) and "attachee" (descendant).
in this environment it is possible (and highly probable) that the "attacher" and the "attachee" do not share a "/tmp" directory in common.
In this scenario the "attacher" must resort to handshaking with the attachee via a /proc in order to access the "attachee's" /tmp from the "attacher".
In order to achieve this rendezvous, the "attachee" must occupy a descendant, or same, (pid) namespace of, or as, the "attacher".
since (pid) namespaces are hierarchical, a descendant process (in its own descendent pid namespace) will also occupy all its ancestor (pid) namespaces (between it and the 'root' or 'host' pid namespace) with a unique pid in each of those "interstitial" (pid) namespace(s).
thus the "attachee" "/tmp" is accessible, via an "ancestor's" (or peer's) /proc filesystem using the pid of the "attachee" that is associated with it in that (pid) namespace.
thus an "ancestor" "attacher" can handshake with a descendant "attachee" in this fashion.
therefore an "attacher" has two choices when attempting to attach:
- use the /proc/<pid>/root/tmp path to the "attachee's" /tmp
- this works with both peers and descendants
- use /tmp
- this only works if the "attacher" and "attachee" share a /tmp in common
the obvious choice is to default to /proc/<pid>/root/tmp however there is an issue with this; should the attachee have elevated privileges, the attacher may not have r/w permission on the attachee's /proc/<pid>/root path.
In these circumstances, the "attacher" can only resort to /tmp which may or may not be in common with the "attachee".
the logic required for an "attacher" to determine if an "attachee" /tmp *is* in common unfortunately requires read access (from the attacher) to the
"attachee's" /proc filesystem (namely to read namespace identities and to
also 'stat(2)' the /proc/<pid>/root/tmp directory to obtain device and inode values for comparison in order to determine if "/tmp" is in common.
when the "attachee" has elevated privileges, this access is not available to the "attacher".
therefore in such circumstances, the "attacher" has no choice but to attempt
to use /tmp and simply timeout the handshake if in fact the "attachee" does not share a /tmp in common