jak znaleźć przestrzeń nazw dla konkretnego procesu?

Odpowiedzi:

39

Spróbuję odpowiedzieć zarówno na to, jak i na twoje wcześniejsze pytanie, ponieważ są one powiązane.

Drzwi do przestrzeni nazw to pliki w /proc/*/ns/*i /proc/*/task/*/ns/*.

Przestrzeń nazw jest tworzona przez proces, który nie udostępnia swojej przestrzeni nazw. Przestrzeń nazw może być na stałe przez Dowiązywanie ten nsplik w jakimś innym miejscu.

Tak ip netnsdziała na przykład przestrzeń nazw netto . Dzieli netprzestrzeń nazw i łączy się /proc/self/ns/netz nimi ./run/netns/netns-name

W /proczamontowanym w głównej przestrzeni nazw pid możesz wyświetlić listę wszystkich przestrzeni nazw, które mają w nich proces, wykonując:

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

Liczba w nawiasach kwadratowych to liczba i-węzłów.

Aby uzyskać to dla danego procesu:

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

Teraz mogą istnieć trwałe przestrzenie nazw, które nie zawierają żadnego procesu. Znalezienie ich może być o wiele trudniejsze AFAICT.

Po pierwsze, trzeba pamiętać, że może być kilka zamontować nazw.

# 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

Ci /mnt/1/a, /run/netns/amoże być pliki nazw.

Możemy uzyskać numer i-węzła:

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

Ale to nie mówi nam wiele innych niż to, że nie ma go na powyższej liście.

Możemy spróbować wpisać go jako dowolny z różnych typów:

# 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, to był netplik przestrzeni nazw.

Wydaje się więc, że mamy metodę wylistowania przestrzeni nazw: wylistuj nskatalogi wszystkich zadań, a następnie znajdź wszystkie procpunkty montowania we wszystkich /proc/*/task/*/mountinfoi wymyśl ich typ, próbując je wprowadzić.

Stéphane Chazelas
źródło
19

Jeśli posiadasz program util-linux v2.28 lub nowszy , możesz użyć 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

Korekta: lsns nie jest dostępny w wersji ut-linux v2.27, jak mawiano w tej odpowiedzi. Zobacz https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

Rfraile
źródło
Znalazłem też fajny skrypt Pythona dla starszych Linuksa. opencloudblog.com/?p=251
Neil McGill
lsnsjest bardzo przydatny, ale pokazuje tylko najniższy PID w każdej przestrzeni nazw - tzn. nie może powiedzieć przestrzeni nazw dla dowolnego dowolnego PID. W każdym razie +1, ponieważ nadal jest to przydatna odpowiedź, nawet jeśli nie odpowiada bezpośrednio na pytanie.
cas
9
$ ip netns identify $PID

gdzie $PIDjest identyfikator procesu, który można uzyskać na różne sposoby.

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

Ken Sharp
źródło
1
Zauważ, że jest to tylko dla sieciowych nazw i tylko tych utworzonych przy pomocy ip netns(lub przynajmniej utworzonych przez coś, co bind-mount zamyka drzwi przestrzeni nazw w / run / netns jak ip netnsrobi). Zasadniczo szuka w / run / netns plików, które są takie same jak /proc/$PID/ns/net.
Stéphane Chazelas
Co? /run/netnsnawet nie istnieje na moim komputerze.
Ken Sharp
/run/netnslub wszędzie tam, gdzie ipbind montuje pliki specjalne przestrzeni nazw. findmnt -t nsfsmoże powiedzieć ci, gdzie to jest w twoim systemie. OTOH, jeśli to zrobisz unshare -n sleep 1000 & ip netns identify "$!", nic nie dostaniesz.
Stéphane Chazelas,
findmnt -t nsfs- nic. unshare -n sleep 1000 & ip netns identify "$!"- unshare: unshare failed: Operacja niedozwolona
Ken Sharp
Potrzebujesz uprawnień administratora (CAP_SYS_ADMIN), aby utworzyć nowe sieci. findmnt -t nsfszwracanie niczego nie sugeruje, że nie masz żadnych sieci w bankomacie swojego komputera.
Stéphane Chazelas,
9

psteraz ma opcji wydruku dla różnych rodzajów nazw związanych z procesami: ipcns, mntns, netns, pidns, userns, i utsns. W przypadku tego pytania istotnym jest przestrzeń nazw PID lub pidns.

więc jeśli chcesz znaleźć identyfikator przestrzeni nazw PID dla np. pid 459:

# ps -h -o pidns -p 459
4026532661

i aby wyświetlić listę wszystkich procesów w tej przestrzeni nazw:

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

lub za pomocą pgrep, możesz przejść bezpośrednio z PID do listy wszystkich procesów współużytkujących tę samą przestrzeń nazw PID:

pgrep -a --ns 459

W przeciwieństwie do ps, pgrepmoże ograniczyć dane wyjściowe do określonej przestrzeni nazw (jeśli znasz PID jednego z procesów w nim zawartych), ale ma bardzo ograniczone możliwości formatowania danych wyjściowych (tylko PID lub PID i ich wiersze poleceń)

Zawsze możesz przesłać dane wyjściowe pgrep --ns 459do, xargs ps -faby uzyskać potrzebne informacje o procesie.

cas
źródło
0

Lister przestrzeni nazw :

Możesz użyć listns.py

Zastosowanie: ./listns.pylub python2 listns.pyAby dokładnie odpowiedzieć na to pytanie, możesz grepować wynik w ten sposób python2 listns.py | grep $PID(zastąp zmienną pid)

Źródło: github-mirror i artykuł w całości dzięki Ralfowi Trezeciakowi

Sieciowe przestrzenie nazw :

W przypadku sieciowej przestrzeni nazw ip netns identify $PIDmożna użyć.

Nsutils

Podaj, pidnslistże zwraca przestrzeń nazw pid procesu

$ pidnslist -ss 8782
pid:[4026531836] 
intika
źródło