TCP Socket висит - обе стороны застряли в sendto () - PullRequest
1 голос
/ 15 сентября 2011

У нас есть приложение linux (у нас нет исходного кода), которое кажется зависшим. Сокет между двумя процессами сообщается как ESTABLISHED, и в буфере сокета ядра есть некоторые данные (хотя они и не находятся рядом с настроенным 16M через wmem / rmem). Оба конца сокета, похоже, застряли в sendto ().

Ниже приведено несколько исследований с использованием netstat / lsof и strace:

ХОСТ А (10.152.20.28)

[root@hosta ~]# lsof -n -u df01 | grep 12959 | grep 12u
q         12959 df01   12u  IPv4            4398449                TCP 10.152.20.28:38521->10.152.20.29:gsigatekeeper (ESTABLISHED)

[root@hosta ~]# netstat -anp | grep 38521
tcp   268754  90712 10.152.20.28:38521          10.152.20.29:2119           ESTABLISHED 12959/q

[root@hosta ~]# strace -p 12959
Process 12959 attached - interrupt to quit
sendto(12, "sometext\0somecode\0More\0exJKsss"..., 542, 0, NULL, 0 <unfinished ...>
Process 12959 detached
[root@hosta~]#

ХОСТ В (10.152.20.29)

[root@hostb ~]# netstat -anp | grep 38521
tcp    72858 110472 10.152.20.29:2119           10.152.20.28:38521          ESTABLISHED 25512/q

[root@hostb ~]# lsof -n -u df01 | grep 38521
q         25512 df01   14u  IPv4            6456715                 TCP 10.152.20.29:gsigatekeeper->10.152.20.28:38521 (ESTABLISHED)

[root@hostb ~]# strace -p 25512
Process 25512 attached - interrupt to quit
sendto(14, "\0\10\0\0\0Owner\0sym\0Type\0Ctpy\0Time\0Lo"..., 207, 0, NULL, 0 <unfinished ...>
Process 25512 detached
[root@hostb~]#

Мы обновили драйвер NIC до последней и самой лучшей версии. Системы работают под управлением RHEL 5.6 x64 (2.6.18-238.el5), я проверил eratta для RHEL 5.7 и 5.8, но я не вижу упоминаний об ошибках в драйвере bnx2 или ядре.

У кого-нибудь есть идеи, как отлаживать это дальше?

1 Ответ

3 голосов
/ 15 сентября 2011

Читает ли любая из сторон?Если нет, возможно, что приемные буферы обеих сторон заполнены, что приводит к тому, что данные не отправляются (из-за заполнения окна приема), что приводит к заполнению обоих буферов отправки, что приведет к блокировке sendto.(Возможно, это может произойти, несмотря на то, что вы установили wmem / rmem, если приложение устанавливает параметры сокета SO_RCVBUF и SO_SNDBUF.)

Чтобы отладить это, я синхронизировал бы часы обеих машин, затемЗапустите оба приложения под strace с параметрами -e trace=network и -tt, чтобы вы могли сравнить журналы и посмотреть, не читает ли приложение.

Вы также можете использовать сетевой анализатор (например, Wireshark ), чтобы определить, не застревает ли окно приема TCP на 0.

Если это так, вы, вероятно, можете обойти это, создав небольшой прокси-сервер кэширования, который будет выполнять recv / sendс обеих сторон, буферизуя то, что не может быть отправлено в то время.

...