Мой опыт в разработке и отладке Parallels Virtuozzo Containers позволил обобщить и сформулировать список пожеланий к описанию проблемы пользователя, который позволяет существенно уменьшить время диагностирования и решения проблемы в ядре операционной системы Linux. Прошу отметить, что при всей очевидности некоторых рекомендаций многие участники open-source сообщества по-прежнему пренебрегают ими. Алгоритм представлен подкатом.
Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/networking/netconsole.txt
Documentation/trace/ftrace.txt
tcpdumpt at Wikipedia
strace at Wikipedia
- Описание проблемы.
Самое главное, что вы должны сделать, это точно описать проблему и действия, которые приводят к ней. Любая, даже самая мелкая деталь, может быть важна. К этому же пункту можно отнести вопрос: «Как часто баг воспроизводится?».
- Версия ядра.
Лучше если вы приложите к багу вывод команды:
# uname -a
- Где вы взяли ядро?
Ядро linux распространяется как в бинарном виде, так и в исходных кодах. В баге важно указать точную версию ядра и кем оно было собрано. Если вы его собрали самостоятельно, нужно приложить конфиг и так же может понадобится vmlinux или модуль. При падениях разработчики нередко сопоставляют дизассемблированный код и код на С, чтобы определить точное место, где произошел баг.
- Логи ядра.
Пожалуй для индивидуальных пользователей это самая сложная тема. Наиболее надежный способ сбора логов — последовательный порт и вторая машина. Дома такая возможность есть не у всех, да и последовательные порты стали редкостью.
Следующим шагом была netconsole. С ней вам достаточно на одной машине настроить rsyslogd для сбора логов через сеть и прописать ее адрес на всех серверах. Этот способ может не работать, особенно если баг связан с сетью.
Netconsole упростила настройку сбора логов с серверов, но проблема пользователей оставалась актуальна, и был придуман kdump. На данный момент это самый мощный и в то же время самый ненадежный механизм. В случае крэша системы на диск сохраняется образ памяти. В дальнейшем его можно открыть утилитой crash и узнать состояние всех процессов, логи ядра, значение памяти по заданному адресу и т п. Он чем-то похоже на core файл, который откладывают приложения в случае падения.
- Версия и название дистрибутива и приложений непосредственно связанных с проблемой.
Это только кажется, что ядро лежит под пользовательскими приложениями, и их работа зависит от поведения ядра. Но часто бывает что и поведение ядра зависит от пользовательских приложений.
- Проблемы с сетью.
Какие-то пакеты не доходят до адресатов или наоборот что-то лишнее просачивается через фильтры. В этом случае полезно приложить лог tcpdump-а с обоих сторон.
- Sysrq
Это такая магическая комбинация клавиш. Зажимаем Alt и нажимаем последовательно Prt-Scr и букву. Если нажать H, то в логах ядра появится небольшая помощь.
Самой распространенной ситуацией применения sysrq являются все возможные зависания. Для начала стоит нажать L, что распечатает информацию о том чем занят каждый процессор в данный момент. T — распечатывает состояние каждого процесса. Так же с помощью этих клавиш можно убить все процессы, кроме init-а, сбросить данные из памяти на диск, перезагрузить машину, отправить машину в panic, показать состояние таймеров и памяти и т д.
- Параметры загрузки
O параметрах ядра можно прочитать в Documentation/kernel-parameters.txt. В случае возникновения бага я бы рекомендовал включить следующие:
sysrq_always_enabled — включается магические клавиши sysrq
debug — повышает уровень логирования ядра
earlyprintk — печатать лог ядра на ранней стадии. Эту опцию стоит включить, если машина на загрузке ничего не выдает и зависает.
Так же рекомендовал бы убрать опцию quiet, которая в некоторых дистрибутивах включена по умолчанию. С ней ядро не печатает часть логов.
Дополнительные средства отладки.
- Debug ядра.
Вы наверное замечали, что в дистрибутивах чаще всего два ядра одной версии. Одно из них имеет префикс debug. Это ядро работает немного медленнее и содержит ряд дополнительных проверок. Например: оно заполняет освобожденную память специальным шаблоном, проверяет, чтоб ядро не засыпало с запрещенными прерываниями, отслеживает порядок взятия блокировок и т д.
Если у вас баг воспроизводится стабильно, то будет нелишним попробовать воспроизвести его на debug ядре и предоставить логи именно с него.
- Tracer
Этот пункт скорее для совсем продвинутых пользователей, которые хотят сами разобраться с проблемой.
Интерфейс к этому механизму полностью реализован в debugfs:
mount debugfs -t debugfs /debug
cd /debug/tracing
Есть два вида трейсеров. Первый — это события, разработчики явно в коде сообщают о них. И второй ftrace — это трейсер, который показывает, в каком порядке вызывались функции ядра. Все события от трейсеров могут фильтроваться, включаться и выключаться отдельно. В случае если события отключены, то они практически не влияют на производительность ядра.
И в заключение несколько полезных советов.
- Приложение работает некорректно или зависает. Попробуйте воспользоваться утилитой strace, она показывает все системные вызовы с аргументами и кодом возврата.
- Процесс находится в состоянии D «uninterruptible sleep”. Скореe всего процесс находится в ядре. Можно попытаться посмотреть в /proc/[PID]/stack и /proc/[PID]/status.
- Если у вас случился panic. Просмотрите лог с самого начала. Часто в конце лога находятся сообщения об ошибках, которые являются следствием предыдущих. Баг нужно забить на первую ошибку.
- Для того чтобы ядро откладывало дампы памяти на диск, нужно загрузить ядро с опцией crashkernel=128M, установить на машину kexec-tools и запустить сервис kdump. Дампы будут сохраняться в /var/crash
- Лог ядра можно достать из дампа ядра при помощи утилиты makedumpfile:
makedumpfile —dump-dmesg vmcore log.txt
Ссылки
Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/networking/netconsole.txt
Documentation/trace/ftrace.txt
tcpdumpt at Wikipedia
strace at Wikipedia