Уже давно при интерактивной инсталляции RHEL/CentOS/Rocky и других дистрибутивов сразу после завершения процесса нам предлагают сконфигурировать Kdump. Некоторые инженеры от предложения отказываются – и зря. Участок резервируемой памяти не такой уж и большой, а при паниках системы или же зависаниях возможность создать дамп критически важна. Возникают неприятные ситуации, когда этот файл просто необходим. Случилась такая и у нас. Поэтому мы решили написать эту статью – о сrashdump’е и о том, для чего Kdump в Linux, как его правильно готовить и как с минимальными затратами подготовить стенд для последующего анализа дампов.

Что такое дамп и зачем он нужен?
Crash dump, kernel dump, kernel core dump, core dump, dump — это всё разные названия одного и того же файла, который создается, когда ОС приходит в состояние паники. Файл включает в себя необходимую для исследования проблемы информацию: заголовки программ, содержимое памяти, содержимое регистров CPU и т. д. Примерно в 99% случаев дампы имеют формат ELF (Executable and Linkable Format) – поэтому остановимся только на нем.
Операционные системы (ОС) тоже паникуют
Причин для паники не очень много:
1. ОС столкнулась с программной проблемой, которую не может решить. Чтобы не повредить данные, она уходит в панику.
2. ОС столкнулась с аппаратной проблемой.
3. ОС умышленно «спаниковали», чтобы получить дамп.
4. ОС зависла и watchdog «спаниковал» ее.
При каждом таком событии нам нужно сохранить состояние системы для последующего ее анализа.
Как ОС записывают дамп
Методов у операционки для создания дампов несколько:
1. Ядро ОС входит в состояние паники и самостоятельно записывает дамп.
2. Ядро ОС переключается в специальное диагностическое ядро, и уже оно записывает дамп.
3. Некая прошивка или гипервизор сохраняет содержимое памяти без участия ОС.
Например, в RHEL/CentOS/Rocky используется второй метод, что позволяет сохранять дамп, даже если проблема произошла в «основном» ядре.
А теперь к механике
Теперь отдельно стоит остановиться на механизме работы Kdump. После его активации наша система работает с двумя ядрами. Одно (first kernel) используется для работы, а под другое (dump-capture kernel) мы резервируем участок памяти. Это нужно для того, чтобы при аварии (естественной или искусственно вызванной пользователем) выполнить системный вызов kexec() и переключиться в него для последующего сохранения содержимого памяти. Для наглядности приводим симпатичную схему:

Про то, как установить и настроить Kdump, написано много статей и заметок, поэтому хочется только напомнить, что дамп может быть сохранен не только локально. В конфигурационном файле /etc/kdump.conf есть большая секция настроек:
[root@server-centos ~]# tail -20 /etc/kdump.conf #raw /dev/vg/lv_kdump #ext4 /dev/vg/lv_kdump #ext4 LABEL=/boot #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 #nfs my.server.com:/export/tmp #ssh user@my.server.com #sshkey /root/.ssh/kdump_id_rsa path /var/crash core_collector makedumpfile -l --message-level 1 -d 31 #core_collector scp #kdump_post /var/crash/scripts/kdump-post.sh #kdump_pre /var/crash/scripts/kdump-pre.sh #extra_bins /usr/bin/lftp #extra_modules gfs2 #default shell #force_rebuild 1 #force_no_rebuild 1 #dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3" #fence_kdump_args -p 7410 -f auto -c 0 -i 10 #fence_kdump_nodes node1 node2
По умолчанию благодаря настройкам нас балуют только «path» с указанием локальной папки и коллектором, позволяющим отфильтровать ненужные страницы памяти. Однако существуют ситуации, когда записать данные на локальную файловую систему не получится по нескольким причинам:
- проблема с дисковой подсистемой;
- проблема с файловой системой;
- нехватка места в /var/crash.
В таких случаях правильным enterprise-решением будет централизованное хранение дампов с сохранением их по сети. Для этого у нас есть два параметра на выбор — nfs и ssh.
Вот мы и получили dump. Что дальше?
В былые времена у нас был выбор: исследовать его самостоятельно или понести дамп вендору, чтобы он в нем сам покопался и предложил какое-то решение (или не предложил, тут уже как повезет). Сейчас приходится рассчитывать только на себя. Анализ дампа — это отдельная история, требующая много времени, кофе, слез и пушистого котика.
Но конечно же, без практической части мы вас не отпустим и рассмотрим создание стенда для анализа таких дампов для популярных клонов RHEL. Его можно делать на чём угодно: VMware, VirtualBox, KVM, Hyper-V -- на самом деле, это не имеет значения. Если у вас есть дамп, то его можно проанализировать в спокойной обстановке у себя в стенде.
Общий алгоритм прост:
1. Устанавливаем нужную ОС в виртуальную машину.
2. Устанавливаем все обновления.
3. Устанавливаем утилиту “crash”.
4. Устанавливаем “kernel-debuginfo” той же версии, что и на «спаниковавшем» сервере.
5. Загружаем в виртуальную машину дамп и анализируем. Тут очень подходит мем про рисование совы:

1. Если понадобится проанализировать дамп другого сервера с более поздним ядром, то обновляем “kernel-debuginfo”. Если с более ранним, то “yum remove kernel-debuginfo*”, и ставим нужную нам версию (помните: одновременно может быть установлена только одна версия).
В основном мы ориентировались на докум��нтацию от Red Hat, статья же о клонах:
· Какие версии с какими ядрами выходили https://access.redhat.com/articles/3078
· RHEL 6 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s1-kdump-crash
· RHEL 8 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/managing_monitoring_and_updating_the_kernel/analyzing-a-core-dump_managing-monitoring-and-updating-the-kernel#doc-wrapper
· RHEL 9 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/analyzing-a-core-dump_managing-monitoring-and-updating-the-kernel#doc-wrapper
Теперь разберем на примерах (для архитектуры x86_64).
**CentOS 6**
Да, он уже EOL, но в корпоративных дата-центрах не редкость (там и не такое попадается). Скачиваем нужные образ и контрольную сумму, проверяем:
· https://vault.centos.org/6.10/isos/x86_64/CentOS-6.10-x86_64-minimal.iso
· https://vault.centos.org/6.10/isos/x86_64/sha256sum.txt
Установку можно проводить с параметрами по умолчанию. Советую делать это на странице, где будут спрашивать имя сервера: нажать Configure Network и настроить сеть. В противном случае вам придется делать это после установки и вручную править файлы в “/etc/sysconfig/network-scripts/”. В более поздних версиях мы имеем NetworkManager из коробки даже в минимальных комплектациях, так что через `nmtui` можно будет легко настроить сеть.
Теперь нам понадобятся рабочие репозитории. Они настраиваются неочевидно из-за того, что версия ОС стала EOL (от root):
``` cd /etc/yum.repos.d/ mkdir old mv *.repo old/ mv old/CentOS-Debuginfo.repo . sed -i 's/enabled=0/enabled=1/' CentOS-Debuginfo.repo vi c610.repo ```
Прописыва��м вот такие репозитории:
Hidden text
``` [CentOS_6.10_base] name=CentOS 6.10 Base baseurl=http://vault.epel.cloud/6.10/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 enabled=1 metadata_expire=never [CentOS_6.10_updates] name=CentOS 6.10 Updates baseurl=http://vault.epel.cloud/6.10/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 enabled=1 metadata_expire=never [CentOS_6.10_extras] name=CentOS 6.10 Extras baseurl=http://vault.epel.cloud/6.10/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 enabled=1 metadata_expire=never [CentOS_6.10_contrib] name=CentOS 6.10 Contrib baseurl=http://vault.epel.cloud/6.10/contrib/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 enabled=0 metadata_expire=never [CentOS_6.10_centosplus] name=CentOS 6.10 CentOSPlus baseurl=http://vault.epel.cloud/6.10/centosplus/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 enabled=0 metadata_expire=never ```
Это включит архивные репозитории из CentOS Vault. Ранее мы включили до сих пор не убранный в архив репозиторий для дебага. Теперь осталось только “yum update -y && yum install -y crash && reboot”, и у нас получится готовая заготовка для стенда. Будет нелишним сделать снэпшот получившейся виртуальной машины.
Теперь представим, что у нас спаниковал сервер с CentOS 6.2 и ядром `2.6.32-220`. Нам нужно проанализировать дамп. В этом случае берем `yum install kernel-debuginfo-2.6.32-220.el6.x86_64`, потом грузим на виртуальную машину файл `vmcore`, используем:
` # crash /usr/lib/debug/lib/modules/2.6.32-220.el6.x86_64/vmlinux /путь/до/собранного/с/упавшего/сервера/vmcore
Файл дампа на спаниковавшем сервере будет в “/var/crash/timestamp/vmcore”, если вы не меняли настройки. Если не получается определить точное название нужного пакета для анализа, смотрите, какие есть в http://debuginfo.centos.org/6/x86_64/.
**CentOS 7**
Тут проще, так как он еще поддерживается. Качаем и проверяем контрольную сумму (можно и с другого зеркала):
· https://mirror.yandex.ru/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
· https://mirror.yandex.ru/centos/7.9.2009/isos/x86_64/sha256sum.txt
Затем ставим от root :
# sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo && yum update -y && yum install -y crash && reboot
Что же касается установки `kernel-debuginfo` и дальнейшего анализа, всё по аналогии с CentOS 6. Имена пакетов можно посмотреть на http://debuginfo.centos.org/7/x86_64/
**CentOS 8.5**
Речь пойдет о EOL классической версии, что перестали поддерживать вопреки обещаниям не в 2028 году, а в 2021-м: https://blog.centos.org/2020/12/future-is-centos-stream/ . Тем не менее многие люди успели себе ее поставить. Начинаем как обычно, качаем и проверяем контрольную сумму:
· https://vault.centos.org/8.5.2111/isos/x86_64/CentOS-8.5.2111-x86_64-boot.iso
· https://vault.centos.org/8.5.2111/isos/x86_64/CHECKSUM
Так как это EOL, то с netinstall, что мы скачали, придется после настройки сети указать место для скачивания пакетов руками в Installation Source:
https://vault.centos.org/8.5.2111/BaseOS/x86_64/os/
и указать в Software Selection, что нам нужен Minimal Install.
После установки придется снова вручную настраивать архивные репозитории от root:
``` cd /etc/yum.repos.d/ mkdir old mv *.repo old/ mv old/CentOS-Linux-Debuginfo.repo . sed -i 's/enabled=0/enabled=1/' CentOS-Linux-Debuginfo.repo vi c85.repo ```
Прописываем вот такие репозитории:
``` [baseos] name=CentOS Linux 8.5 - BaseOS baseurl=https://vault.centos.org/8.5.2111/BaseOS/x86_64/os/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial metadata_expire=never [appstream] name=CentOS Linux 8.5 - AppStream baseurl=https://vault.centos.org/8.5.2111/AppStream/x86_64/os/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial metadata_expire=never ```
После этого достаточно выполнить:
# yum update -y && yum install -y crash
Установку `kernel-debuginfo` и дальнейший анализ делаем по аналогии с CentOS 6. Имя пакетов можно посмотреть на http://debuginfo.centos.org/8/x86_64/Packages/.
**Rocky Linux 8**
Качаем и проверяем сумму (можно и с другого зеркала):
· https://mirror.yandex.ru/rockylinux/8.9/isos/x86_64/Rocky-8.9-x86_64-minimal.iso
· https://mirror.yandex.ru/rockylinux/8.9/isos/x86_64/CHECKSUM
Ставим:
# yum update -y && yum install -y crash
А вот с репозиториями для `kernel-debuginfo` сложнее, так как в отличие от CentOS нет общего для всех подверсий каталога с отладочными файлами, он отдельный для каждой подверсии.
Если нужны отладочные заголовки для текущего ядра из 8.9, то достаточно включить текущий репозиторий отладки для BaseOS и вставить из него:
Hidden text
``` [root@localhost ~]# uname -r 4.18.0-513.5.1.el8_9.x86_64 [root@localhost ~]# head /etc/yum.repos.d/Rocky-Debuginfo.repo # Rocky-Debuginfo.repo # [baseos-debug] name=Rocky Linux $releasever - BaseOS - Source mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever-debug #baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/debug/tree/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial [root@localhost ~]# vi /etc/yum.repos.d/Rocky-Debuginfo.repo [root@localhost ~]# head /etc/yum.repos.d/Rocky-Debuginfo.repo # Rocky-Debuginfo.repo # [baseos-debug] name=Rocky Linux $releasever - BaseOS - Source mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever-debug #baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/debug/tree/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial [root@localhost ~]# yum update Rocky Linux 8 - BaseOS - Source 5.1 kB/s | 3.1 kB 00:00 Dependencies resolved. Nothing to do. Complete! [root@localhost ~]# yum install kernel-debuginfo-4.18.0-513.5.1.el8_9.x86_64 Last metadata expiration check: 0:00:23 ago on Mon 27 Nov 2023 01:28:28 PM MSK. Dependencies resolved. ================================================================================================================================================================================================== Package Architecture Version Repository Size ================================================================================================================================================================================================== Installing: kernel-debuginfo x86_64 4.18.0-513.5.1.el8_9 baseos-debug 657 M Installing dependencies: kernel-debuginfo-common-x86_64 x86_64 4.18.0-513.5.1.el8_9 baseos-debug 75 M Transaction Summary ================================================================================================================================================================================================== Install 2 Packages Total download size: 732 M Installed size: 3.8 G Is this ok [y/N]: n Operation aborted. [root@localhost ~]# ```
Имена доступных пакетов можно посмотреть тут: https://mirror.yandex.ru/rockylinux/8.9/BaseOS/x86_64/debug/tree/Packages/k/
А вот если нужны заголовки для более старой версии, то придется подключать уже архив. Вот пример для 8.7:
Hidden text
``` [root@localhost ~]# vi /etc/yum.repos.d/debug87.repo [root@localhost ~]# yum update Rocky Linux 8.7 - BaseOS - Source 1.2 MB/s | 3.3 MB 00:02 Last metadata expiration check: 0:00:01 ago on Mon 27 Nov 2023 01:34:51 PM MSK. Dependencies resolved. Nothing to do. Complete! [root@localhost ~]# cat /etc/yum.repos.d/debug87.repo [baseos-8.7-debug] name=Rocky Linux 8.7 - BaseOS - Source baseurl=https://dl.rockylinux.org/vault/rocky/8.7/BaseOS/x86_64/debug/tree/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial [root@localhost ~]# yum install kernel-debuginfo-4.18.0-425.13.1.el8_7.x86_64 Last metadata expiration check: 0:00:47 ago on Mon 27 Nov 2023 01:34:51 PM MSK. Dependencies resolved. ================================================================================================================================================================================================== Package Architecture Version Repository Size ================================================================================================================================================================================================== Installing: kernel-debuginfo x86_64 4.18.0-425.13.1.el8_7 baseos-8.7-debug 638 M Installing dependencies: kernel-debuginfo-common-x86_64 x86_64 4.18.0-425.13.1.el8_7 baseos-8.7-debug 72 M Transaction Summary ================================================================================================================================================================================================== Install 2 Packages Total download size: 710 M Installed size: 3.7 G Is this ok [y/N]: n Operation aborted. [root@localhost ~]# ```
Посмотреть возможные версии kernel-debuginfo можно тут: https://dl.rockylinux.org/vault/rocky/8.7/BaseOS/x86_64/debug/tree/Packages/k/
Для 8.8, 8.6 и более старых делаем по аналогии.
**Rocky Linux 9**
Качаем и проверяем сумму (можно и с другого зеркала):
+ https://mirror.yandex.ru/rockylinux/9.3/isos/x86_64/Rocky-9.3-x86_64-minimal.iso
+ https://mirror.yandex.ru/rockylinux/9.3/isos/x86_64/CHECKSUM
Потом ставим `dnf update -y && dnf install -y crash`. А вот с репозиториями для `kernel-debuginfo` делаем наподобие 8.9. Для текущей версии:
Hidden text
``` [root@localhost ~]# uname -r 5.14.0-362.8.1.el9_3.x86_64 [root@localhost ~]# grep -A8 baseos-debug /etc/yum.repos.d/rocky.repo [baseos-debug] name=Rocky Linux $releasever - BaseOS - Debug mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever-debug$rltype #baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/debug/tree/ gpgcheck=1 enabled=0 metadata_expire=6h gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 [root@localhost ~]# vi /etc/yum.repos.d/rocky.repo [root@localhost ~]# grep -A8 baseos-debug /etc/yum.repos.d/rocky.repo [baseos-debug] name=Rocky Linux $releasever - BaseOS - Debug mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever-debug$rltype #baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/debug/tree/ gpgcheck=1 enabled=1 metadata_expire=6h gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 [root@localhost ~]# dnf update Rocky Linux 9 - BaseOS 6.0 kB/s | 4.1 kB 00:00 Rocky Linux 9 - BaseOS - Debug 774 kB/s | 854 kB 00:01 Rocky Linux 9 - AppStream 8.6 kB/s | 4.5 kB 00:00 Dependencies resolved. Nothing to do. Complete! [root@localhost ~]# dnf install kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64 Last metadata expiration check: 0:00:31 ago on Mon 27 Nov 2023 02:13:43 PM MSK. Error: Problem: conflicting requests - nothing provides kernel-debuginfo-common-x86_64 = 5.14.0-362.8.1.el9_3 needed by kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64 from baseos-debug (try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages) [root@localhost ~]# ```
Здесь, как видите, нарываемся на ошибку, которая находится на стороне разработчиков Rock (забыли собрать нужный пакет). Пакета просто нет в https://mirror.yandex.ru/rockylinux/9.3/BaseOS/x86_64/debug/tree/Packages/k/.
К счастью, этот изъян можно поправить, скачав пакет и распаковав его:
``` [root@localhost ~]# dnf download kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64 Last metadata expiration check: 0:09:10 ago on Mon 27 Nov 2023 02:13:43 PM MSK. kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64.rpm 3.7 MB/s | 611 MB 02:44 [root@localhost ~]# ls anaconda-ks.cfg kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64.rpm [root@localhost ~]# mkdir 5.14.0-362.8.1.el9_3 [root@localhost ~]# mv kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64.rpm 5.14.0-362.8.1.el9_3/ [root@localhost ~]# cd 5.14.0-362.8.1.el9_3/ [root@localhost ~]# rpm2cpio kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64.rpm | cpio -idmv ### тут был длинный вывод, что я удалил (можете без -v запускать, тогда не будет) [root@localhost 5.14.0-362.8.1.el9_3]# ls -l total 625776 -rw-r--r--. 1 root root 640792453 Nov 27 14:25 kernel-debuginfo-5.14.0-362.8.1.el9_3.x86_64.rpm drwxr-xr-x. 3 root root 17 Nov 27 14:29 usr [root@localhost 5.14.0-362.8.1.el9_3]# ls usr/lib/debug/lib/modules/5.14.0-362.8.1.el9_3.x86_64/ internal kernel partner vdso vmlinux [root@localhost 5.14.0-362.8.1.el9_3]# ```
Как видим, у нас сейчас в `/root/5.14.0-362.8.1.el9_3/usr/lib/debug/lib/modules/5.14.0-362.8.1.el9_3.x86_64/` лежит искомый `vmlinux`. Можно будет `crash /root/5.14.0-362.8.1.el9_3/usr/lib/debug/lib/modules/5.14.0-362.8.1.el9_3.x86_64/ /путь/до/собранного/с/упавшего/сервера/vmcore`
Если же нужно проанализировать дамп более старого ядра из состава Rocky 9.0, то по аналогии с 8.7 выше настраиваем архивный репозиторий:
``` [root@localhost ~]# vi /etc/yum.repos.d/debug90.repo [root@localhost ~]# cat /etc/yum.repos.d/debug90.repo [baseos-debug-9.0] name=Rocky Linux 9.0 - BaseOS - Debug baseurl=https://dl.rockylinux.org/vault/rocky/9.0/BaseOS/x86_64/debug/tree/ gpgcheck=1 enabled=1 metadata_expire=6h gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 [root@localhost ~]# dnf update Rocky Linux 9.0 - BaseOS - Debug 632 kB/s | 863 kB 00:01 Dependencies resolved. Nothing to do. Complete! [root@localhost ~]# dnf install kernel-debuginfo-5.14.0-70.30.1.el9_0.x86_64 Last metadata expiration check: 0:00:04 ago on Mon 27 Nov 2023 02:44:37 PM MSK. Error: Problem: conflicting requests - nothing provides kernel-debuginfo-common-x86_64 = 5.14.0-70.30.1.el9_0 needed by kernel-debuginfo-5.14.0-70.30.1.el9_0.x86_64 from baseos-debug-9.0 (try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages) [root@localhost ~]# ```
Как видим из https://dl.rockylinux.org/vault/rocky/9.0/BaseOS/x86_64/debug/tree/Packages/k/: тут тоже не собран нужный пакет. По аналогии скачиваемся и распаковываем.
В наших планах написать еще один материал о Kdump. Он будет посвящен анализу одного любопытного кейса из нашей практики.
