IP netns монитор, не работающий в сценарии

Я пытаюсь использовать ip netns monitor в сценарии для реакции на создание новых сетевых пространств имен, например:

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

Однако я никогда не вижу вывода от ip netns monitor в этом варианте использования. Дальнейшее экспериментирование показывает, что я никогда не вижу вывода от ip netns monitor если это перенаправляется или передается по каналу.

Вот простой пример того, что действительно дает ожидаемый результат:

$ 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 назад к этой реализации монитора: http://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/ip/ipnetns.c?id=3c61c01a666d9f4dbb871305ab6791e19ede7d4a#n462

Я не вижу ничего очевидного в источнике, который вызвал бы поведение измениться на основе того, где на STDOUT указывают - но я все еще плохо знаком со всем этим.

Есть ли некоторый способ, которым я должен использовать ip netns monitor так, чтобы это работало в сценарии? Или я должен повышать ошибку где-нибудь?

Если это действительно повреждается, я могу попробовать обходное решение inotifywait вместо этого.

Моя система:

$ 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

Обновление

Я выполнил и интерактивные и перенаправленные варианты с strace и результаты следуют.

Метод:

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

Кроме некоторых адресов и дескрипторов, strace показывает ту же инициализацию для обоих. То, где они варьируются, следует за первым чтением от inotify.

Интерактивный (т.е. без | 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>, "\1\0\0\0\0\1\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 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>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007ffe9273d400] write(1</dev/pts/0>, "delete dummy\n", 13delete dummy) = 13

Перенаправленный (т.е. с | cat) производит:

[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>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 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>, "\1\0\0\0\0\1\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32

Так, при перенаправлении fstat имеет различные результаты (как и следовало ожидать), но write никогда не называется. Результаты read покажите, что уведомления проникают как ожидалось. И ip netns monitor должно быть радо, что нет никакой ошибки, потому что это сохраняет цикличное выполнение.

2
задан 6 April 2015 в 00:19

1 ответ

Я беру предположение, что это - возможно Вы поражающий проблему, где stdout на канале буферизует в 4K. См. https://unix.stackexchange.com/a/25378 для некоторых идей зафиксировать его. Для подтверждения это - конкретный вопрос, попытайтесь менять имя фиктивного файла к чему-то намного большему, или касание/комнату вызова многократно, генерировать достаточно вывода для удара размера буфера по умолчанию.

3
ответ дан 6 April 2015 в 00:19

Другие вопросы по тегам:

Похожие вопросы: