Диагностика ядра Linux

Сбои в ядре Linux приводят к возникновению чрезвычайно разнообразных симптомов. Некоторые авторы дают следующую неполную классификацию проблем, с которыми может столкнуться пользователь:
  • kernel oops — проблема при выполнении кода в ядре, например кто-нибудь попытался разыменовать нулевой указатель. С кем из программистов на C такого не случалось?
  • kernel panic — кто-то попытался разыменовать нулевой указатель в обработчике прерываний. После чего ядро уходит в полную несознанку и начинает мигать caps-lock-ом.
  • soft lockup ­— что-то заблокировалось (вероятно наткнувшись на не освобожденную блокировку), несмотря на это прерывания продолжают обрабатываться. Хорошее упражнение — попинговать машину или попытаться зажечь numlock.
  • hard lockup — компьютер жужжит вентиляторами и ни на что не реагирует. Провести какую-то диагностику в этом случае особенно сложно. Проблема может быть вызвана как вышедшим из строя железом, так и неаккуратной обработкой прерываний.
кроме того, можно добавить:
  • hung — индуцированное неправильной блокировкой последовательное попадание всех или большинства процессов системы в состояние TASK_UNINTERRUPTIBLE (известного так-же как D-состояние, по обозначению в top или ps). Согласно книге Р.Лава такой «наводящий ужас» процесс нельзя убить, завершить, и вообще что-то с ним сделать. При этом с точки зрения пространства пользователя программа просто заблокирована на каком-то системном вызове (например ввода-вывода). При попадании в подобное состояние всех критических процессов системы можно получить симптом похожий на soft lockup.
Получить как можно более подробную информацию о сути возникающей проблемы важно как для правильного написания сообщения об ошибке, так и для временного переконфигурирования системы с целью избегания выполнения проблемного кода и повышения её живучести.

К счастью, ядро обладает неким набором средств первичной самодиагностики, пригодным для постановки примерного диагноза. Согласно, видимо всеобщей, философской парадигме, наиболее устойчивыми и надежными являются наиболее простые подсистемы, поэтому сообщения ядра имеет смысл искать в текстовой и последовательной консолях. Конечно, при достаточном уровне везения нужное сообщение будет сброшено syslog-демону, записано на диск, отправлено по сети на удаленный syslog-демон и прочее, но при недостаточном везении монитор (и фотоаппарат на телефоне), клавиатура и COM-порт являются последней надеждой.

printk


Одним из механизмов общения ядра с внешним миром является printk. При неправильной настройке сообщение скорее всего будет просто потеряно как не обладающее значимостью. Для настройки используется /proc/sys/kernel/printk, соответствующий ему параметр sysctl, утилита klogconsole, SysRq-клавиша и т.п. Ядро обладает восемью уровнями важности сообщений, поэтому установка уровня в 8 заведомо напечатает все на консоль.

sysrq


Магическая кнопка включается в /proc/sys/kernel/sysrq или соответствующим ему параметром sysctl. Предлагается просто записать туда 1, несмотря на то, что новые ядра позволяют изысканный контроль над функционалом. В данной ситуации незачем себя ограничивать, хотя для нормальной работы разумно ограничить функционал на случай случайных нажатий. Если осталась рабочая терминальная сессия (например удаленная сессия по ssh), можно использовать как альтернативу, например, echo b > /proc/sysrq-trigger; с последовательной консоли поведение активируется кнопкой 'break'.

Важно помнить, что SysRq-w, например, выдает сообщение с уровнем KERN_INFO, то есть выдача printk должна быть настроена правильно, чтобы можно было что-то увидеть. Полный список команд SysRq.

softlockup_panic


Параметр ядра softlockup_panic или параметр kernel.softlockup_panic для sysctl включают панику ядра при обнаружении soft lockup. Описание внутреннего устройства. Включение паники позволит остановить выполнение системы и проанализировать выдачу, снабженную трассировкой, хотя контроль блокировки исполняется постоянно. Существует аналогичный механизм отслеживания hard lockup для многопроцессорных систем (если остались живые процессоры — есть шанс что сработает), с соответствующим параметром hardlockup_panic. Время срабатывания обычно в пределах одной минуты.

hung_task_timeout_sec


Механизм отслеживания процессов, надолго застрявших в состоянии TASK_UNINTERRUPTIBLE, параметры настраиваются через sysctl и /proc:
  • kernel.hung_task_panic — включает/отключает панику при обнаружении не прерываемого процесса;
  • kernel.hung_task_warnings — счетчик сообщений. Иными словами, если паника отключена, будет сообщено о таком количестве зависших процессов;
  • kernel.hung_task_timeout_secs — сколько секунд процесс должен непрерывно пробыть в TASK_UNINTERRUPTIBLE, чтобы вызвать сообщение. По умолчанию бывает либо выключено (0), либо очень большое число порядка 10 минут.
Сообщения снабжаются трассировкой, которая подсказывает в какой подсистеме происходит сбой.

FastCGI в Lighttpd и Nginx

Сравнение настроек, приводящих к одинаковому результату в Lighttpd и Nginx.

Настройки Lighttpd:
url.rewrite-once += ( "^/testfc$" => "/testfc/", )

fastcgi.server += ( 
        "/testfc" => ((
                        "bin-path" => "/path/to/fcgi/server.py",
                        "socket" => socket_dir + "/viewvc.sock",
                        "max-procs" => 1,
                        "check-local" => "disable",
                        "fix-root-scriptname" => "enable",
        ))
)

Настройки Nginx:
location /testfc/ {
                fastcgi_pass unix:/path/to/fcgi/sock;
                fastcgi_split_path_info ^(/testfc)(.*)$;
                fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param  PATH_INFO $fastcgi_path_info;
                fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_path_info;
                include        fastcgi_params;
        }

Nginx сам запускать приложения не умеет, поэтому об этом нужно заботиться заранее. Например можно использовать изысканное решение с помощью systemd.