ip netns monitor não está funcionando em um script

2

Estou tentando usar ip netns monitor em um script para reagir à criação de novos namespaces de rede, por exemplo:

ip netns monitor | while read ACTION NETNS; do
 echo 'handling it!'
done

No entanto, nunca vejo nenhuma saída de ip netns monitor neste caso de uso. Mais experimentos revelam que nunca vejo qualquer saída de ip netns monitor se for redirecionada ou canalizada.

Aqui está um exemplo simples do que dá o resultado esperado:

$ ip netns monitor &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
add dummy
delete dummy

E aqui está outro exemplo de uso que produz saída zero :

$ ip netns monitor >/tmp/ip-netns-monitor.log 2>&1 &
$ ip netns monitor | cat &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
$ cat /tmp/ip-netns-monitor.log
# no results

Eu acompanhei minha versão de ip de volta para esta implementação do monitor: link

Eu não vejo nada de óbvio na fonte que poderia causar comportamento para mudar com base em onde STDOUT é apontado - mas eu ainda sou novo em tudo isso.

Existe alguma maneira de usar ip netns monitor para que funcione em um script? Ou eu deveria estar criando um bug em algum lugar?

Se isso estiver realmente quebrado, posso tentar uma solução alternativa com inotifywait .

Meu sistema:

$ ip -Version
ip utility, iproute2-ss131122
$ lsb_release --description
Description:    Ubuntu 14.04.2 LTS
$ uname -rvm
3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:36:28 UTC 2015 x86_64

Atualizar

Eu executei as variantes interativas e redirecionadas com strace e os resultados seguem.

Método:

while true; do touch /var/run/netns/dummy ; sleep 2; rm /var/run/netns/dummy; sleep 2; done &
strace -ivy ip netns monitor
strace -ivy ip netns monitor | cat

Além de alguns endereços e alças, o strace mostra a mesma inicialização para ambos. Onde eles variam está seguindo a primeira leitura de inotify.

Interativo (isto é, sem | cat ) produz:

[00007ffe9274c767] inotify_init()       = 4
[00007ffe9274c737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007ffe9273d3a0] read(4<anon_inode:inotify>, "
[00007f607d90e767] inotify_init()       = 4
[00007f607d90e737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "
ip netns monitor | while read ACTION NETNS; do
 echo 'handling it!'
done
$ ip netns monitor &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
add dummy
delete dummy
$ ip netns monitor >/tmp/ip-netns-monitor.log 2>&1 &
$ ip netns monitor | cat &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
$ cat /tmp/ip-netns-monitor.log
# no results
$ ip -Version
ip utility, iproute2-ss131122
$ lsb_release --description
Description:    Ubuntu 14.04.2 LTS
$ uname -rvm
3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:36:28 UTC 2015 x86_64
while true; do touch /var/run/netns/dummy ; sleep 2; rm /var/run/netns/dummy; sleep 2; done &
strace -ivy ip netns monitor
strace -ivy ip netns monitor | cat
[00007ffe9274c767] inotify_init()       = 4
[00007ffe9274c737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007ffe9273d3a0] read(4<anon_inode:inotify>, "
[00007f607d90e767] inotify_init()       = 4
[00007f607d90e737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32
[00007f607d8fed84] fstat(1<pipe:[154785]>, {st_dev=makedev(0, 8), st_ino=154785, st_mode=S_IFIFO|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2015/04/05-21:04:54, st_mtime=2015/04/05-21:04:54, st_ctime=2015/04/05-21:04:54}) = 0
[00007f607d90855a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f607dffc000
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007ffe9273cd84] fstat(1</dev/pts/0>, {st_dev=makedev(0, 12), st_ino=3, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 0), st_atime=2015/04/05-20:55:28, st_mtime=2015/04/05-20:55:36, st_ctime=2015/04/05-04:17:42}) = 0 [00007ffe9274655a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffe92e3a000 [00007ffe9273d400] write(1</dev/pts/0>, "add dummy\n", 10add dummy) = 10 [00007ffe9273d3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007ffe9273d400] write(1</dev/pts/0>, "delete dummy\n", 13delete dummy) = 13
%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007f607d8fed84] fstat(1<pipe:[154785]>, {st_dev=makedev(0, 8), st_ino=154785, st_mode=S_IFIFO|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2015/04/05-21:04:54, st_mtime=2015/04/05-21:04:54, st_ctime=2015/04/05-21:04:54}) = 0 [00007f607d90855a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f607dffc000 [00007f607d8ff3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007f607d8ff3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007ffe9273cd84] fstat(1</dev/pts/0>, {st_dev=makedev(0, 12), st_ino=3, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 0), st_atime=2015/04/05-20:55:28, st_mtime=2015/04/05-20:55:36, st_ctime=2015/04/05-04:17:42}) = 0 [00007ffe9274655a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffe92e3a000 [00007ffe9273d400] write(1</dev/pts/0>, "add dummy\n", 10add dummy) = 10 [00007ffe9273d3a0] read(4<anon_inode:inotify>, "%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%dummy%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%", 4096) = 32 [00007ffe9273d400] write(1</dev/pts/0>, "delete dummy\n", 13delete dummy) = 13

Redirecionado (isto é, com | cat ) produz:

%pre%

Assim, quando redirecionado fstat tem resultados diferentes (esperado), mas write nunca é chamado. Os resultados de read mostram que as notificações estão chegando como esperado. E ip netns monitor deve estar feliz, não há erro porque continua em loop.

    
por Jason Stangroome 05.04.2015 / 03:14

1 resposta

3

Suponho que você esteja possivelmente tendo problemas com o stdout em buffers de cachimbo em 4K. Consulte o link para obter algumas ideias sobre como corrigi-lo. Para confirmar que este é o seu problema específico, tente alterar o nome do seu arquivo fictício para algo muito maior ou chame várias vezes o touch / rm para gerar saída suficiente para atingir o tamanho do buffer padrão.

    
por Joshka 06.04.2015 / 00:05