Процесс под FreeBSD 9.0 зависает в беспрерывном сне без системного вызова (пустой wchan)
У меня есть собственный процесс регистрации, который читает из STDIN и отправляет данные через TCP на размеченный сервер регистрации. В моем случае STDIN - это журнал доступа, который подключен к Apache httpd 2.2, например, в httpd.conf: CustomLog "|/usr/local/bin/serelog" default
Мой процесс serelog иногда переходит в непрерывный сон под FreeBSD 9.0 и не возвращается из него. Он работает надежно под другими операционными системами, включая FreeBSD 8, Linux 2.6 и Linux 3.1.
Как я могу узнать, что может быть причиной беспрерывного сна?
Общая структура выглядит следующим образом: httpd -[PIPE]-> serelog -[TCP-CONNECTION]-> scribed
До сих пор я делал следующий анализ:
- Используя ps: stat это "D", а wchan это "-". Так что, по-видимому, нет системного вызова, который не имеет для меня особого смысла, так как этот процесс находится в непрерывном сне и должен быть на земле ядра.
- Поскольку процесс находится в состоянии "D", процесс не реагирует на kill -9, как ожидалось.
- Прикрепление фермы к serelog извне из оболочки: пока ферма прикреплена, serelog работает плавно. Вскоре (секунды) после отсоединения фермы от serelog, serelog переходит в состояние "D".
- При подключении фермы к serelog ПОСЛЕ того, как она вошла в состояние "D", ферма ничего не печатает
- В состоянии "D" lsof показывает, что входящая PIPE заполнена. Это ожидается, так как в состоянии "D" процесс "спит" и больше не может читать. Исходящее TCP-соединение пустое.
- Если я убью "окружающий" сервер Apache httpd, процесс serelog в итоге завершится через (например) 40 минут.
- Проверка того, что другие сообщают на форумах о непрерываемой проблеме, не удалась: в моей настройке нет NFS. И поскольку это сервер, пользователь также не взаимодействует с дисководами компакт-дисков или подключаемым оборудованием.
Так что теперь я застрял в процессе, который является непрерывным, очевидно, не в системном вызове и надежно работает при отслеживании. Единственная хорошая вещь - это то, что я могу воспроизвести поведение за несколько секунд или минут, когда отправляю много HTTP-запросов через JMeter loadtest (5 потоков в JMeter).
Любые советы по отладке, настройке параметров ядра приветствуются.
Привет
1 ответ
Эта проблема оказалась реальной ошибкой ядра FreeBSD, и теперь она исправлена в ядре.
Ссылка на PR: http://www.freebsd.org/cgi/query-pr.cgi?pr=166340
Предлагаемый патч: http://lists.freebsd.org/pipermail/freebsd-bugs/2012-May/048610.html