我希望在每个现有的网络名称空间中打开一个netlink套接字,以侦听与接口关联的LINK消息。我想从一个过程开始。
根据setns()
文档-"给定一个引用命名空间的文件描述符,将调用线程与该命名空间重新关联。"。因此,我可以通过简单地使用pthread_create()
为我需要的每个名称空间创建一个线程,调用setns()
然后打开netlink套接字来实现我的任务吗?
我问的原因是因为我看到了关于setns()
作用于进程名称空间的相互矛盾的信息。
简短的回答:是的,你可以…因为您正在处理网络名称空间。
长答:
不同类型的linux内核名称空间有时具有不同的约束,这些差异会使您偏离轨道。一个非常好的来源是michael Kerrisk的set手册页(2)。特别是标题为"特定名称空间类型的详细信息"的部分。(不支持深度链接)。
对于将进程或线程切换到不同的网络命名空间,适用如下:
Network, IPC, time, and UTS namespaces
In order to reassociate itself with a new network, IPC,
time, or UTS namespace, the caller must have the
CAP_SYS_ADMIN capability both in its own user namespace
and in the user namespace that owns the target namespace.
请注意,网络名称空间是"扁平的",因此它们不会形成任何层次结构。
相比之下,PID名称空间有不同的约束,最明显的原因是它们确实形成了层次结构:
Reassociating with a PID namespace is allowed only if the
target PID namespace is a descendant (child, grandchild,
etc.) of, or is the same as, the current PID namespace of
the caller.
然后是完全不同的:挂载名称空间。
A process can't join a new mount namespace if it is
sharing filesystem-related attributes (the attributes
whose sharing is controlled by the clone(2) CLONE_FS flag)
with another process.
这是一种稍微复杂的方式,表示一旦您的进程中有另一个线程(=第一个任务),那么该进程的任何线程的挂载名称空间都不能再更改,无论是第一个任务还是任何其他任务。