A página de manual do Linux para namespaces de rede(7) diz:
Os namespaces de rede fornecem isolamento dos recursos do sistema associados à rede: [...], o diretório /sys/class/net, [...].
No entanto, simplesmente mudar para um namespace de rede diferente não parece alterar o conteúdo de /sys/class/net
(veja abaixo como reproduzir). Estou apenas enganado aqui ao pensar que o namespace setns()
da rede já é suficiente? É sempre necessário remontar /sys
para obter a /sys/class/net
correspondência correta do namespace de rede atualmente associado? Ou estou perdendo alguma coisa aqui?
Exemplo para reproduzir
Pegue um sistema *ubuntu, encontre o PID do rtkit-daemon, insira o namespace de rede do daemon, mostre suas interfaces de rede e verifique /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 ...
Observe que, embora ip link show
corretamente mostre apenas lo
, /sys/class/net
mostra todas as interfaces de rede visíveis no namespace de rede "raiz" (e no namespace de montagem "raiz").
No caso de rtkit-daemon
também entrar no namespace mount dele não faz diferença: sudo nsenter -t $PID -n -m
e depois ls /sys/class/net
ainda mostra as interfaces de rede não presentes no namespace da rede.
"Fixar"
Muitos elogios para @Danila Kiver por explicar o que realmente está acontecendo nos bastidores do kernel Linux. A remontagem sysfs
enquanto o namespace de rede correto é associado mostrará as entradas corretas/sys/class/net
em :
$ 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
Portanto, isso agora produz os resultados corretos em /sys/class/net
.
Vamos analisar
man 5 sysfs
:Portanto, de acordo com esta página de manual, a saída de
ls /sys/class/net
deve depender do namespace de rede dols
processo. Mas... O comportamento real não parece ser o descrito nesta página de manual. Existe uma boa documentação do kernel sobre como ele funciona .Cada
sysfs
montagem tem uma tag de namespace associada a ela. Essa tag é definida quando o sysfs é montado e depende do namespace de rede do processo de chamada . Cada entrada sysfs (por exemplo, uma entrada em/sys/class/net
) também pode ter uma tag namespace associada a ela.Quando você itera sobre o diretório sysfs, o kernel obtém a tag namespace do sysfs mount e, em seguida, itera sobre as entradas, filtrando aquelas que têm tag namespace diferente .
Então, acontece que os resultados da iteração sobre o
/sys/class/net
dependem do namespace de rede do processo que iniciou a/sys
montagem em vez do namespace de rede do processo atual, portanto, você deve sempre montar/sys
no namespace de rede atual (de qualquer processo pertencente para este namespace) para ver os resultados corretos.