Kernel Oops при запуске VPN: доказательства, которые стоит сохранить
Сбой при запуске VPN требует подходящей сборки ядра и первой трассировки, а не снимка последней строки. Решите, что сохранить, прежде чем перезагружаться снова.
Запуск VPN-клиента — это удобная метка времени, а не причина, и именно это различие определяет, что произойдёт дальше. Когда Oops ядра возникает рядом с этим моментом, выбор — между сбором пригодного отчёта о сбое и провокацией того же сбоя ещё пять раз на боевой машине. Сохраните четыре вещи до перезагрузки: точную сборку ядра, первую трассировку сбоя, состояние taint и краткое описание всего остального, что изменилось в ту же минуту. Остальное — интерпретация, и она может подождать, пока доказательства не окажутся в безопасном месте.
Поймайте первый сбой, а не последнюю строку
Первый Oops в журнале — тот, который имеет значение, потому что каждый последующий сбой может быть побочным уроном от уже нездорового ядра. Скопируйте заголовок вместе с трассировкой вызовов, поскольку заголовок несёт сбойную инструкцию и состояние регистров, определяющее путь кода. Отчёт, начинающийся с последней строки, стоит очень мало для того, кто прочитает его через неделю.
Если машина уже перезагрузилась, буфер ядра предыдущей загрузки часто всё ещё находится в журнале, при условии, что тогда было включено постоянное хранилище. Читайте его из сохранённого файла, а не воссоздавайте нагрузку, потому что второе воспроизведение может перезаписать то, что вам нужно. Там, где машина не может хранить журнал между перезагрузками, последовательная консоль или netconsole — единственный способ, которым сбой когда-либо станет видимым.
Зафиксируйте сборку, прежде чем читать любой символ
Имена функций и смещения имеют смысл только относительно бинарного файла, который их создал, поэтому запишите строку выпуска ядра и идентификатор сборки дистрибутива вместе. Файл символов из другой сборки с полной уверенностью указывает на неверную строку, что хуже, чем вовсе не иметь символа. Сохраняйте версию пакета ядра, а не только номер upstream, потому что дистрибутивы многое переносят назад.
Модули вне дерева заслуживают отдельной строки в записи, поскольку ядро с taint ограничивает то, что сопровождающий вправе заключить. Читайте значение taint, а не выводите его из списка модулей.
Ненулевой taint — это не обвинение и не делает отчёт бесполезным. Он сообщает читателю, какие компоненты были загружены в момент сбоя, и некоторые флаги приводят к тому, что отчёт понижается в приоритете по политике, а не по решению. Запишите значение, имена модулей и то, запускались ли когда-нибудь то же оборудование и нагрузка на ядре без них. Именно это последнее сравнение отделяет новую регрессию от давней ошибки.
Отделите триггер от дефекта
Запуск туннеля обычно задействует путь, который уже существовал: сетевой драйвер, дисциплину очереди, функцию offload или состояние питания. Триггер объясняет, когда сбой появляется, а не какой код неверен, и отношение к триггеру как к причине ведёт к серии изменений конфигурации, которые ничего не исправляют.
Работающий прежний образ — это доказательство, а не доказанность. При сравнении меняйте один компонент на загрузку и храните результаты там, где они переживут машину.
Проверьте, что сопровождающий действительно может использовать
Прочитайте отчёт так, как прочитал бы посторонний, прежде чем отправлять. Если конфигурация, точная последовательность и идентичность сборки присутствуют, а учётные данные удалены, отчёт пригоден. Если это снимок трассировки стека, он вернётся с запросом тех же сведений. Руководство по поиску ошибок ядра описывает, как выглядят полезная трассировка и подходящие символы.
uname -r
cat /proc/sys/kernel/tainted
journalctl -k -b -1 --no-pager | sed -n '/BUG:/,/Call Trace/p'
dmesg -T | grep -A 40 'RIP:'
Каждая команда выше только читает состояние, и первые две следует выполнить до следующей перезагрузки, если машина ещё может на них ответить. Там, где журнал не сохраняется, именно эти две — единственные, что когда-либо снова заработают.
Удалите ключи, пароли и посторонний трафик, но сохраните имена функций и смещения, которые кому-то нужны для чтения трассировки. Отправляйте материал по тому пути отчётности, который относится к дистрибутиву или ядру, а не через публичную вставку с приложенным именем хоста. Затем ждите вопроса, а не собирайте новые сбои, потому что локализованный сбой против подходящей сборки — единственный результат, который двигает отчёт вперёд. Если ничего не вернётся, запасной вариант — контролируемое воспроизведение на резервном оборудовании, никогда на машине, от которой зависят другие люди.