Již jsem položil otázku, jak vypsat všechny jmenné prostory v Linuxu, ale nebyly žádné správné a přesné odpovědi, takže chci najít metodu, která mi může pomoci zjistit jmenný prostor PID nějakého procesu nebo skupiny procesy. Jak to lze provést v Linuxu?
Přijatá odpověď:
Pokusím se odpovědět na tuto i vaši předchozí otázku, protože spolu souvisí.
Dveře do jmenných prostorů jsou soubory v /proc/*/ns/*
a /proc/*/task/*/ns/*
.
Jmenný prostor je vytvořen procesem zrušení sdílení jeho jmenný prostor. Jmenný prostor pak může být trvalý pomocí připojení k připojení ns
soubor na nějaké jiné místo.
To je to, co ip netns
dělá například pro net jmenné prostory. Zruší sdílení své net
jmenný prostor a připojení připojení /proc/self/ns/net
na /run/netns/netns-name
.
V /proc
připojený v kořenovém jmenném prostoru pid, můžete vypsat všechny jmenné prostory, které mají v sobě proces, takto:
# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]
Číslo v hranatých závorkách je číslo inodu.
Chcete-li to získat pro daný proces:
# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Nyní může existovat trvalé jmenné prostory, které v sobě nemají žádný proces. Zjistit je může být mnohem složitější AFAICT.
Nejprve musíte mít na paměti, že připojení může být několik jmenné prostory.
# 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
Tyto /mnt/1/a
, /run/netns/a
mohou být soubory jmenného prostoru.
Můžeme získat číslo inodu:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
Ale to nám neříká nic jiného, než že to není ve výše vypočítaném seznamu.
Můžeme to zkusit zadat jako kterýkoli z různých typů:
# 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
#
Dobře, to byla net
soubor jmenného prostoru.
Zdá se tedy, že máme metodu, jak vypsat jmenné prostory:vypsat ns
adresáře všech úloh a poté najděte všechny proc
přípojné body ve všech /proc/*/task/*/mountinfo
a zjistit jejich typ pokusem o jejich zadání.