TL;DR: по каким причинам процесс засыпает в uninterruptible sleep на сокете и как это пофиксить?
Есть такая утилита для скачивания файлов по http/https/ftp — axel. Вчера я качал ей вот этот конкретный URL: http://dlc.openindiana.org/isos/hipster/latest/OI-hipster-gui-20171031.usb — и столкнулся с uninterruptible sleep. Если нужны подробности: в сорцах программы используется обычный select() на сокете с тайм-аутом.
Через пару минут работы программа засыпает в ядре и спит (ориентировочно) 10-15 минут. На SIGKILL не реагирует. То есть это классический uninterruptible sleep. Через 10-15 минут сон прерывается, программа обнаруживает свои разорванные соединения, переустаналивает их и работает дальше. (Если за время сна не получала SIGKILL, разумеется.)
Файл я таки докачал, но за время скачивания она так засыпала 4 раза.
Мой вопрос в том, какое сочетание факторов (состояние сети, настройки ядра...) приводит к долгому uninterruptible sleep на сокете и как настроить таймаут. Axel по умолчанию выставляет таймаут 120 секунд, но в данном случае, видимо, срабатывает не его таймаут, а какой-то ядерный таймаут (на другом уровне сетевой модели?), который значительно больше.
Если просто вырубить маршрутизатор во время скачки, ядро обнаруживает разорванное соединение сразу, и программа не зависает во сне. Но если она уже уснула, никакие манипуляции с сетью не приводят к тому, чтобы ядро разбудило программу. Довольно странное поведение, как по мне. Прошу сетевого ликбеза.