как узнать пространство имен конкретного процесса?

25

Я уже задавал вопрос о том, как перечислить все пространства имен в Linux , но не было никаких правильных и точных ответов, поэтому я хочу найти метод, который может помочь мне найти пространство имен PID какого-либо процесса или группы процессы. Как это можно сделать в Linux?

zerospiel
источник

Ответы:

39

Я постараюсь ответить на этот и ваш предыдущий вопрос, поскольку они связаны между собой.

Двери в пространства имен - это файлы в /proc/*/ns/*и /proc/*/task/*/ns/*.

Пространство имен создается процессом, не разделяющим его пространство имен. Пространство имен может быть сделано постоянным, затруднительное-монтажным на nsфайл в другом месте.

Вот что ip netnsделает, например, для сетевых пространств имен. Он разделяет свое netпространство имен и привязывается /proc/self/ns/netк ./run/netns/netns-name

В /procсмонтированном в пространстве имен корневого pid вы можете перечислить все пространства имен, в которых есть процесс, выполнив:

# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]

Число в квадратных скобках - это номер индекса.

Чтобы получить это для данного процесса:

# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid

Теперь могут существовать постоянные пространства имен, в которых нет процессов. Найти их может быть намного сложнее, AFAICT.

Во-первых, вы должны иметь в виду, что может быть несколько пространств имен mount .

# 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

Те /mnt/1/a, /run/netns/aмогут быть файлами пространство имен.

Мы можем получить номер индекса:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a

Но это не говорит нам о многом, кроме того, что это не в списке, вычисленном выше.

Мы можем попробовать ввести его как любой из различных типов:

# 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
#

ОК, это был netфайл пространства имен.

Таким образом, казалось бы, у нас есть метод для перечисления пространств имен: перечислите nsкаталоги всех задач, затем найдите все точки procмонтирования во всех /proc/*/task/*/mountinfoи выясните их тип, пытаясь ввести их.

Стефан Шазелас
источник
19

Если у вас есть util-linux v2.28 или выше, вы можете использовать lsns :

# lsns
        NS TYPE  NPROCS   PID USER             COMMAND
4026531836 pid       78     1 root             /sbin/init
4026531837 user      79     1 root             /sbin/init
4026531838 uts       78     1 root             /sbin/init
4026531839 ipc       78     1 root             /sbin/init
4026531840 mnt       75     1 root             /sbin/init
4026531857 mnt        1    12 root             kdevtmpfs
4026531957 net       79     1 root             /sbin/init
4026532393 mnt        1  1214 root             /lib/systemd/systemd-udevd
4026532415 mnt        1  2930 systemd-timesync /lib/systemd/systemd-timesyncd
4026532477 mnt        1 32596 root             -bash
4026532478 uts        1 32596 root             -bash
4026532479 ipc        1 32596 root             -bash
4026532480 pid        1 32596 root             -bash

Исправление: lsns недоступен в util-linux v2.27, как говорил этот ответ. См. Https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes.

Rfraile
источник
Я также нашел хороший скрипт на python для тех, кто работает на старых Linux. opencloudblog.com/?p=251
Нил Макгилл
lsnsочень полезен, но он показывает только самый низкий PID в каждом пространстве имен - т.е. он не может сказать вам пространство имен для любого произвольного PID. +1 в любом случае, потому что это все еще полезный ответ, даже если он не дает прямого ответа на вопрос.
Cas
9
$ ip netns identify $PID

где $PIDидентификатор процесса, который вы можете получить различными способами.

http://man7.org/linux/man-pages/man8/ip-netns.8.html

Кен Шарп
источник
1
Обратите внимание, что это только для сетевых пространств имен и только тех, которые созданы с использованием ip netns(или, по крайней мере, созданы чем-то, что привязывает-монтирует двери пространства имен в / run / netns, как это ip netnsделает). В основном он ищет в / run / netns файлы, которые совпадают с /proc/$PID/ns/net.
Стефан Шазелас
Какая? /run/netnsдаже не существует на моем компьютере.
Кен Шарп
/run/netnsили везде, где ipbind-монтирует специальные файлы пространства имен. findmnt -t nsfsможет сказать вам, где он находится в вашей системе. OTOH, если вы это сделаете unshare -n sleep 1000 & ip netns identify "$!", вы ничего не получите.
Стефан
findmnt -t nsfs- ничего такого. unshare -n sleep 1000 & ip netns identify "$!"- unshare: unshare failed: Операция не разрешена
Ken Sharp
Вам нужны привилегии суперпользователя (возможность CAP_SYS_ADMIN) для создания новых сетей. findmnt -t nsfsвозврат ничего не говорит о том, что у вас нет банкоматов на вашем банкомате.
Стефан
9

psтеперь имеют параметры вывода для различных типов пространств имен , связанных с процессами: ipcns, mntns, netns, pidns, userns, и utsns. Для этого вопроса релевантным является пространство имен PID, или pidns.

поэтому, если вы хотите узнать идентификатор пространства имен PID для, например, pid 459:

# ps -h -o pidns -p 459
4026532661

и перечислить все процессы в этом пространстве имен:

ps -o pidns,pid,cmd | awk '$1==4026532661'

или с помощью pgrep, вы можете перейти непосредственно от PID к списку всех процессов, совместно использующих то же пространство имен PID:

pgrep -a --ns 459

В отличие от этого ps, pgrepможет ограничивать вывод определенным пространством имен (если вы знаете PID одного из процессов в нем), но имеет очень ограниченные возможности форматирования вывода (только PID или PID и их командные строки)

Вы всегда можете трубы выход , pgrep --ns 459чтобы xargs ps -fхотя для получения необходимой информации о процессе.

саз
источник
0

Пространство имен-Листер :

Вы можете использовать listns.py

Использование: ./listns.pyили python2 listns.pyЧтобы точно ответить на этот вопрос, вы можете получить результат, подобный этому python2 listns.py | grep $PID(замените переменную pid)

Источник: github-mirror и статья предоставлены Ralf Trezeciak

Пространства имен сети :

Для сетевого пространства имен ip netns identify $PIDможно использовать.

Nsutils

Обеспечьте, pidnslistчтобы возвращалось пространство имен pid процесса

$ pidnslist -ss 8782
pid:[4026531836] 
intika
источник