Just wanted to come back to this: I noticed that with systemd on Linux there is
a recommended option for longrunning daemons cause PrivateTmp*. This will make
the systemd manager generate a new mount namespace for this new service process
and bind-mount /tmp to an isolated subdirectory in /tmp/systemd-private-*/tmp
This helps against temp file link attacks as the subdir is no longer world
The container aware logic should also work to attach to systemd protected JVMs.
on behalf of TJ Fontaine
Sent: Saturday, April 29, 2017 12:23:13 AM
Subject: [PATCH] attach in linux should be relative to /proc/pid/root and
I have attached a patch that allows jcmd to work against a java process running
inside a Docker container. Apologies if this is not in the correct format. It
built against jdk8u. I couldn’t seem to find an existing JIRA for it.
Diagnostic commands (i.e. jcmd, jstack, etc) fail to attach to a target JVM
that is inside a container (e.g. Docker).
A Linux container often isolates a process in a PID and Mount namespace that is
separate from the "root container" (analogous to the hypervisor/dom0 in
hardware virtualization environments, or the global zone on Solaris). A target
JVM that is isolated in either a PID namespace, or a Mount namespace will fail
the attach sequence.
When the target JVM is in its own PID namespace the pid of the process is
distinct from what the real pid of the process as it relates to the root
container. For example, in the root container you can observe a JVM with a pid
of 17734, however if that JVM is running inside a Docker container the pid
inside its PID namespace is likely 1. So when the target JVM receives the
SIGQUIT it looks in /proc/self/cwd/ for .attach_pid1 however the external
attaching JVM has created the file /proc/17734/cwd/.attach_pid17734. Given this
discrepancy the target JVM will output to stderr thread status, since
/proc/self/cwd/.attach_pid1 doesn't exist and won't continue with the attach
The solution is to parse /proc/pid/status for the field NSpid (available since
Linux 4.1) which contains a list of pids, where the last entry is the "inner
most" PID namespace value. (Namespaces can be stacked, unlike Solaris Zones
which have a virtualization depth of 1)
The rest of the Linux attach sequence assumes a shared mount namespace by
waiting for /tmp/.java_pid17734 to appear. But if the attaching process is in a
separate namespace because the target JVM is in a mount namepsace (or in a
chroot as well) the unix domain socket for attaching won't appear.
Instead the attach sequence should resolve file names relative to
/proc/17734/root which has a materialized view of the rootfs for the target.