Linux

切換到網路命名空間不會改變 /sys/class/net?

  • July 20, 2018

網路命名空間 (7)的 Linux 手冊頁說:

網路命名空間提供與網路相關的系統資源的隔離:

$$ … $$, /sys/class/net 目錄,$$ … $$.

然而,簡單地切換到不同的網路命名空間似乎並沒有改變/sys/class/net(見下文如何重現)的內容。我只是誤以為setns()進入網路名稱空間已經足夠了嗎?是否總是需要重新掛載/sys才能正確/sys/class/net匹配目前加入的網路命名空間?還是我在這裡錯過了其他東西?

重現的例子

拿一個 *ubuntu 系統,找到 rtkit-daemon 的 PID,進入 daemon 的網路命名空間,顯示它的網路介面,然後檢查/sys/class/net

$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2`
$ sudo nsenter -t $PID -n
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ls /sys/class/net
docker0  enp3s0  lo  lxcbr0  ...

請注意,雖然ip link show正確只顯示lo,/sys/class/net顯示在“根”網路命名空間(和“根”掛載命名空間)中可見的所有網路介面。

rtkit-daemon也進入它的掛載命名空間的情況下沒有區別:sudo nsenter -t $PID -n -m然後ls /sys/class/net仍然顯示網路命名空間中不存在的網路介面。

“使固定”

感謝@Danila Kiver解釋了 Linux 核心幕後的真實情況。sysfs 加入正確的網路命名空間時重新安裝將顯示正確條目/sys/class/net

$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2`
$ sudo nsenter -t $PID -n
# MNT=`mktemp -d`
# mount -t sysfs none $MNT
# ls $MNT/class/net/
lo
# umount $MNT
# rmdir $MNT
# exit

所以這現在產生了正確的結果/sys/class/net

讓我們看看man 5 sysfs

/sys/class/net
   Each  of the entries in this directory is a symbolic link representing
   one of the real or virtual networking devices that are visible in 
   the network namespace of the process that is accessing the directory.

所以,根據這個手冊頁, 的輸出ls /sys/class/net必須依賴於ls程序的網路命名空間。但是…實際行為似乎與本手冊中的描述不同。關於它是如何工作的,有一個很好的核心文件

每個sysfs掛載都有一個與之關聯的命名空間標籤。這個標籤是在 sysfs 被掛載時設置的,它依賴於呼叫程序的網路命名空間。每個 sysfs 條目(例如 中的條目/sys/class/net)也可能具有與其關聯的名稱空間標記。

當您遍歷 sysfs 目錄時,核心會獲取sysfs mount 的命名空間標籤,然後它會遍歷條目,過濾掉具有不同命名空間標籤的條目。

因此,事實證明,迭代的結果/sys/class/net取決於啟動/sys掛載的程序的網路命名空間,而不是目前程序的網路命名空間,因此,您必須始終掛載/sys在目前的網路命名空間中(來自任何屬於到此命名空間)以查看正確的結果。

引用自:https://unix.stackexchange.com/questions/457025