Как подружить linux kernel 3.x и утилиту LSI MegaCli

ServeRAID M5015 SAS-SATA ControllerС переходом на ядро Linux 3.x.x владельцы LSI RAID могут столкнуться с неприятным явлением — утилита MegaCli или MegaCli64 перестаёт обнаруживать рейд-контроллер. Ядро правильно определяет и корректно работает, а утилита упорно показывает, что никакого рейд-контроллера нет. Не помогает исправить проблему и обновление MegaCli до последней версии — 8.02.16.

Если мониторинг состояния рейда построен на этой утилите, то ситуация становится совсем неприятной, т.к. можно пропустить вышедший из строя жесткий диск или пришедшую в негодность батарейку кэша.

Попробуем разобраться в ситуации и найти временное решение, до выхода новой версии MegaCli.

Посмотрим версию ядра, наличие LSI MegaRAID и вывод утилиты MegaCli:

[root@farm2:1 ~]# uname -a
Linux farm2.localdomain 3.2.5-3.fc16.x86_64 #1 SMP Thu Feb 9 01:24:38 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

[root@farm2:1 ~]# lspci | grep -i raid
10:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 2108 [Liberator] (rev 05)

[root@farm2:1 ~]# /opt/MegaRAID/MegaCli/MegaCli64 -adpCount

Controller Count: 0.

[root@farm2:1 ~]# /opt/MegaRAID/MegaCli/MegaCli64 -v

MegaCLI SAS RAID Management Tool Ver 8.02.16 July 01, 2011

(c)Copyright 2011, LSI Corporation, All Rights Reserved.

Мы видим, что работаем под управлением linux ядра 3.2.5, есть установленный LSI MegaRAID и  утилита MegaCli64 его не видит. До обновления использовалось ядро 2.6.39, и утилита MegaCli64 обнаруживала контроллер.

Для понимания разницы в поведении MegaCli на ядрах версий 2.6 и 3.х я использовал gdb и strace. Оказалось, что если версия ядра равна 2.6 — используется актуальный набор системных вызовов. Если версия отличается — используются устаревшие системные вызовы ядра 2.4 и, соответственно, контроллер не находится. Первая мысль, которая приходит в голову: подменить системный вызов uname для утилиты MegaCli.  Воспользуемся помощью LD_PRELOAD и несколькими строчками кода на C:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <string.h>

int uname(struct utsname *buf)
{
   int ret = syscall(SYS_uname, buf);
   strcpy(buf->release, "2.6.40");
   return ret;
}

Компилируем:

mkdir fakeuname
cd fakeuname
wget http://supportex.net/files/fakeuname/fakeuname.c
gcc -Wall -fPIC -c fakeuname.c
gcc -Wall -shared -o libfakeuname.so fakeuname.o

Проверим, как будет работать утилита. При запуске будет сообщаться «фейковый» номер версии ядра — 2.6.40, вместо 3.2.5:

[root@farm2:1 fakeuname]# LD_PRELOAD=./libfakeuname.so /opt/MegaRAID/MegaCli/MegaCli64 -adpCount

Controller Count: 1.

[root@farm2:1 fakeuname]# LD_PRELOAD=./libfakeuname.so /opt/MegaRAID/MegaCli/MegaCli64 -AdpAllInfo -aALL

Adapter #0

================================
Versions
================
Product Name :
Serial No : SV12345678
FW Package Build: 12.12.0-0065

Небольшая победа — контроллер определился!
Теперь можно с ним работать, как и раньше. А libfakeuname.so скопировать в более удобное место, например: /usr/local/lib64. И использовать в своих скриптах совместно с LD_PRELOAD=/usr/local/lib64/libfakeuname.so.

Ссылки:

Обновление: Последнюю версию команды setarch, из набора util-linux, дополнили параметром запуска «—uname-2.6». Это позволяет запустить MegaCli без компиляции библиотечной заглушки для uname:

setarch x86_64 —uname-2.6 /opt/MegaRAID/MegaCli/MegaCli64 -adpCount

Добавить комментарий

Ваш e-mail не будет опубликован.