19 нояб. 2013 г.

Анализ падения ядра в Linux (kernel crash dump)

Завалить ядро линукс не так то и просто (если не преднамеренно, конечно), но такое случается... не все баги выловлены, а новые "фишки" приносят новые баги.

Итак, для сохранения дампа при падении ядра в Linux или kernel panic, необходимо настроить сервис kdump и установить несколько дополнительных пакетов.
Сам механизм представляет собой дополнительное маленькое ядро, смысл существования которого состоит в том, чтобы после падения основного ядра системы, перехватить управление, сохранить дамп и перезагрузить систему.

Для Fedora Linux устанавливается всё хозяйство просто командой:

yum install --enablerepo=fedora-debuginfo --enablerepo=updates-debuginfo kexec-tools crash kernel-debuginfo

А вот для Oracle Linux 6.4 чуть сложнее:

yum install crash -y
export DLP="https://oss.oracle.com/ol6/debuginfo"
wget ${DLP}/kernel-uek-debuginfo-`uname -r`.rpm 
wget ${DLP}/kernel-uek-debuginfo-common-`uname -r`.rpm
rpm -Uhv kernel-uek-debuginfo-`uname -r`.rpm kernel-uek-debuginfo-common-`uname -r`.rpm

Команды приведены для текущего ядра системы. Если нужны пакеты для других версий ядра, то нужно указать версию вместо `uname -r`.

Далее, необходимо добавить в конфиг загрузчика (/boot/grub/grub.conf или /boot/efi/EFI/redhat/grub.conf - зависит от того, используется UEFI при загрузке сервера или нет): параметр ядра "crashkernel=128M". Цифра указывает, сколько ОЗУ резервируется под резервное ядро. Через @ можно указать так же смещение в памяти, если необходимо. Например 128M@16 - зарезервирует 128 Мб ОЗУ начиная с физического адреса 0x01000000 (16MB).

Находим запись с нужной версией ядра (или можно ко всем добавить) и в итоге получим что-то в виде:

kernel /boot/vmlinuz-2.6.39-400.109.4.el6uek.x86_64 ro root=UUID=<> rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16   KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet crashkernel=128M

Теперь надо включить службу kdump для автозагрузки:

chkconfig kdump on

Также можно подредактировать конфиг /etc/kdump, но он и по-умолчанию достаточно хорош.
Теперь перезагрузим сервер, чтобы ядро загрузилось с новым параметром:

shutdown -r now

Проверяем, правильно загрузилось ядро с нашими параметрами:

cat /proc/cmdline

Также проверим, работает ли kdump:

service kdump status
Kdump is operational

Теперь, искусственно вызовем kernel panic командой:

echo c > /proc/sysrq-trigger

При этом будет подгружаться маленькое резервное ядро и сохранит дамп. На сохранение дампа нужнон екторое время, потому в определенный момент может показаться, что ядро подвисло - нужно дождаться окончания процесса.

После перезагрузки, мы сможем найти наши дампы (по-умолчанию) в папке /var/crash. Запускаем анализатор дампа:

crash /var/crash/2009-07-17-10\:36/vmcore /usr/lib/debug/lib/modules/`uname -r`/vmlinux

После запуска crash покажет нам некоторую полезную инфу и даст свою командную строку:

GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...

      KERNEL: /usr/lib/debug/lib/modules/2.6.39-400.210.2.el6uek.x86_64/vmlinux
    DUMPFILE: /var/crash/127.0.0.1-2013-11-13-12:04:56/vmcore  [PARTIAL DUMP]
        CPUS: 2
        DATE: Wed Nov 13 12:03:52 2013
      UPTIME: 00:21:58
LOAD AVERAGE: 0.23, 0.17, 0.10
       TASKS: 93
    NODENAME: nagios
     RELEASE: 2.6.39-400.210.2.el6uek.x86_64
     VERSION: #1 SMP Thu Oct 17 16:28:13 PDT 2013
     MACHINE: x86_64  (3292 Mhz)
      MEMORY: 2 GB
       PANIC: "Oops: 0002 [#1] SMP " (check log for details)
         PID: 1902
     COMMAND: "bash"
        TASK: ffff880037a88200  [THREAD_INFO: ffff880037f86000]
         CPU: 1
       STATE: TASK_RUNNING (PANIC)

crash>

Помощь по командам: help или help command

Core dump от любого процесса также можно посмотреть командой: gdb path_to_core
Но, чтобы создавались дампы от процессов необходимо подредактировать файл /etc/limits.conf, например, командой:

sed -i 's/.. *soft *core *0/*\tsoft\t\tcore\t\tunlimited/g' /etc/security/limits.conf

Более подробно по командам можно почитать здесь:
http://docs.oracle.com/cd/E37670_01/E41138/html/ch10s02.html

Всем удачи и поменьше багов! :)