I'll try and answer both this and your earlier question as they are related.
The doors to namespaces are files in /proc/*/ns/*
and /proc/*/task/*/ns/*
.
A namespace is created by a process unsharing its namespace. A namespace can then be made permanent by bind-mounting the ns
file to some other place.
That's what ip netns
does for instance for net namespaces. It unshares its net
namespace and bind-mounts /proc/self/ns/net
to /run/netns/netns-name
.
In a /proc
mounted in the root pid namespace, you can list all the namespaces that have a process in them by doing:
# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]
The number in square brackets is the inode number.
To get that for a given process:
# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Now, there may be permanent namespaces that don't have any process in them. Finding them out can be a lot trickier AFAICT.
First, you have to bear in mind that there can be several mount namespaces.
# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw
Those /mnt/1/a
, /run/netns/a
may be namespace files.
We can get an inode number:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
But that doesn't tell us much other than it's not in the list computed above.
We can try and enter it as any of the different types:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#
OK, that was a net
namespace file.
So it would seem we have a method to list the name spaces: list the ns
directories of all the tasks, then find all the proc
mountpoints in all the /proc/*/task/*/mountinfo
and figure out their type by trying to enter them.
Best Answer
The audit subsystem of the Linux kernel can be very useful to figure out what processes are becoming zombie processes. I just had the following situation:
The cause for these zombie processes is most probably a PHP script, but as these Apache child processes are processing lots of HTTP requests and lots of different PHP scripts, it's very hard to figure out which one could be responsible. Linux has also already deallocated important information of these zombie processes, so we don't even have
/proc/<pid>/cmdline
to figure out which script or-c
command/bin/sh
may have been running:To figure it out, I've installed
auditd
: https://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/I set up the following audit rules:
These rules audit all process creations of the
/bin/dash
binary./bin/sh
doesn't work here, because it's a symlink and audit apparently only sees the target file name:A simple test should now produce audit logs in
/var/log/audit/audit.log
(I've taken the liberty and added a lot of line breaks to improve the readability):Lots of the information is encoded, but
ausearch
can translate it with-i
:If you don't want to restrict the
ausearch
filtering to/bin/dash
, you can also useausearch -i -m ALL
to translate the complete log. Another good filter would beausearch -i -p <PID of a zombie process>
, in this caseausearch -i -p 27800
.Just leave these rules in place until new zombie processes show up, and then search for the process creation of a zombie PID:
This should be very helpful to identify the root cause of the zombie processes. In my case it was a PHP script that used
proc_open
to spawn a Perl script without closing the handle withproc_close
.