“使固定”

“使固定”

Linux 手册页网络命名空间(7)说:

网络命名空间提供与网络相关的系统资源的隔离:[...]、/sys/class/net 目录、[...]。

然而,简单地切换到不同的网络命名空间似乎并没有改变内容/sys/class/net(有关如何重现的信息,请参阅下文)。我是否只是setns()错误地认为网络命名空间已经足够了吗?是否总是需要重新挂载/sys才能正确/sys/class/net匹配当前加入的网络命名空间?或者我在这里还缺少其他东西吗?

重现示例

拿一个 *ubuntu 系统,找到 rtkit-daemon 的 PID,进入该守护进程的网络命名空间,显示其网络接口,然后检查/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但显示全部在“root”网络命名空间(和“root”挂载命名空间)中可见的网络接口。

如果rtkit-daemon还输入挂载命名空间,则没有什么区别:sudo nsenter -t $PID -n -m然后ls /sys/class/net仍然显示网络命名空间中不存在的网络接口。

“使固定”

许多荣誉@丹尼拉·基弗解释 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

答案1

让我们看看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 挂载的命名空间标签,然后迭代条目,过滤掉那些具有不同命名空间标签的

因此,事实证明,迭代的结果取决于/sys/class/net启动挂载的进程的网络名称空间/sys,而不是当前进程的网络名称空间,因此,您必须始终挂载/sys在当前网络名称空间中(从属于任何进程)到此命名空间)以查看正确的结果。

相关内容