LINUX.ORG.RU

[perl][shell] Мониторинг SMART

 ,


0

1

Доброго времени суток.

Пишу я, значит, плагин для nagios, попутно разбираясь с перлом.

Задачи:

  • получить список винтов
  • Для каждого из них прогнать smartctl
  • Если значение увеличивается, ругнуться

Как я поступаю:
при помощи ls /dev/[s,h]d? получаю список винтов. Возникает проблема - если это не винт, а флешка, например, то ничего не работает. Поэтому вопрос: «Как отличить винт от флешки в Perl или shell?»

Далее нужно проверять, не увеличилось ли значение параметра. Если писать всё в какой-нибудь файл, а потом просто сравнивать значение из файла с текущим, то после следующей проверки значение в файле изменится и проблемы не будет видно.
Пока что в голову приходит только одно решение: если файла не существует, создать и записать полученное значение. Затем просто сравнивать не трогая файл.
Есть ли идеи получше?

★★★★

чем входящий в поставку плагин не в кассу?

root@nagios:~# /usr/lib/nagios/plugins/check_ide_smart 
check_ide_smart v1.4.15 (nagios-plugins 1.4.15)
Nagios feature - 1999 Robert Dale <rdale@digital-mission.com>
(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
Copyright (c) 1998-2007 Nagios Plugin Development Team
        <nagiosplug-devel@lists.sourceforge.net>
hizel ★★★★★
()
Ответ на: комментарий от Shtsh

дык путь из /dev/disk/by-path/ сравниваешь с lspci и видишь к какому контроллеру подключено устройство, если USB, то игнорируешь.

А файла нужно 2, один текущий, другой контрольный. Сравниваешь, если разница есть генерируешь событие в nagios'e и переписываешь контрольный файл текущим.

sdio ★★★★★
()
Ответ на: комментарий от hizel

Спасибо за совет, но с перлом нужно же как-то разбираться.
Нет ничего лучше, чем написать что-то бесполезное

Shtsh ★★★★
() автор топика
Ответ на: комментарий от Shtsh

вторая часть проблемы надумана, какой смысл выцеплять жесткие диски если их имена меняются раз в пятилетку

и да, этак вы не перлу научитесь, а его скриптовому подмножеству. имхо раскурить магию перла можно только через книжку за авторством автора языка перл.

hizel ★★★★★
()
Ответ на: комментарий от hizel

hizel

этак вы не перлу научитесь, а его скриптовому подмножеству

Не спорю.
Но сейчас мне важно разобраться именно в практическом применении перла для задач системного администрирования.

Shtsh ★★★★
() автор топика
Ответ на: комментарий от sdio

дык путь из /dev/disk/by-path/ сравниваешь с lspci и видишь к какому контроллеру подключено устройство, если USB, то игнорируешь.

Можно проще: /sys/block/sd?/removable
А в /dev/disk/by-id/ симлинки имеют недвусмысленные префиксы (но я не уверен в надёжности этого метода, т.к. видел там только «scsi» и «usb»).

GotF ★★★★★
()

Критикуйте.

#!/usr/bin/perl

#получаем список дисков в системе
@lsdata = `ls /dev/disk/by-path/* | grep -v usb | grep -v part`;
$number = 0;

$result = "OK: ";
$resultdata = "";

foreach(@lsdata){
        $command = "smartctl -a ".@lsdata[$number];
        @smartdata = `$command`;

#смотрим строчку параметра Reallocated_Sector_Ct
        @reallocated = grep {/Reallocated_Sector_Ct/} @smartdata;
#четвёртое число
        $realcount = (@reallocated[0] =~ /\b([0-9]+)\b/g)[4];
#Делаем имя файла только из цифр, букв, _ и /   
        $filename = "/tmp/check_@lsdata[$number]";
        $filename =~ s%/dev/disk/by-path/%%g;
        $filename =~ s%[\W\\]%%gs;

        if(-e $filename){
#если файл есть, то читаем и сравниваем значения
                open(FILEY,"$filename");
                $file = <FILEY>;
                close(FILEY);
#если увеличилось, то ругаемся
                if($file < $realcount){
                        $result = "CRITICAL: ";
                }
        } else {
                open(FILEH,">$filename");
                print FILEH $realcount;
                close(FILEH);
        }
        $number++;
        $resultdata .= "Disk$number: $realcount; ";
}

print $result . $resultdata . "\n";

Shtsh ★★★★
() автор топика

Smartctl сообщает любопытным, имеется ли у устройства на борту смарт.

Xenesz ★★★★
()
Ответ на: комментарий от Shtsh

критикуйте
@lsdata = `ls /dev/disk/by-path/* | grep -v usb | grep -v part`;

список файлов в перл можно получить через </dev/disk/by-path/*>, так же в перл есть regexp и grep, дальше сам доделаешь

anonymous2 ★★★★★
()
Ответ на: комментарий от Shtsh

Во первых, welcome to our perl band! Perl - это очень подходящий инструмент для административных задач, он конечно может сломать мозг, но он один из немногих языков, от которых можно получать удовольствие при написании кода. Так что - DON'T PANIC AND HAVE FUN.

Замечания по коду:

  • Самое главное: всегда используй use strict и perl -w(use warnings), иначе седые волосы и ночи отладки обеспечены.
  • Как уже сказали - нет смысла использовать вызов ls и grep.
  • Очень странный цикл - в стиле C :
    foreach (@lsdata) {
       ...
       $filename = "/tmp/check_@lsdata[$number]";
    }
    
    Например, можно его переделать так:
    foreach (@lsdata) {
       $filename = '/tmp/check_.'.$_;
    }
    
    А лучше вот так:
    foreach my $data (@lsdata) {
       $filename = '/tmp/check_'.$data;
    }
    
  • Работа с файлами:
    • Всегда используй вызов open с тремя параметрами и всегда указывай режим доступа(чтение/запись...):
      open(FILEY,"$filename"); #плохо, например что будет если $filename это ">blabla"?
      open FILEY, '<', $filename; #хорошо
      
    • Имена файлов: можно использовать escape_filename из модуля File::Util, это более надежно чем придумывать регэкспы самому. В этом же модуле есть много полезных функция для работы с файлами, например для для твоего кода подойдут функции read_file, write_file.
    • ИМХО лучше не создавать для каждого устройства свой файл с информацией а хранить сериализованные данные для всех устройств в одном файле.
  • Немного по стилю:
    • Названия переменных странные: Принято в зависимости от стиля называть переменные так: new_data_ref или NewDataRef или newDataRef, но не newdataref! FILEY, FILEH что это?
    • Комментарии в тех местах где и так все очевидно(точнее будет очевидно. если переменные будут иметь говорящие имена);
    • Конкатенацию лучше использовать там где она реально нужна - т.е. вместо print 'a'.'b'.$some_var можно написать print 'a','b',$some_var
  • Напоследок рекомендую подумать над тем, что скрипт весь скрип будет запускаться с правами рута, хотя на самом деле этого требует только вызов smartctl. Вариантов решения куча, например, посмотреть следующий пункт.
  • Я сам не любитель читать технические книги, но «Книга с верблюдом» это классика, стоит с ней ознакомится, написанна замечательно, недаром Ларри лингвист по образованию. Кроме perl рассмотрены многие интересные темы.
  • Ну и на затравку - кусок кода, которые достает пихает все нужные тебе данные в хэш:
     #!/usr/bin/perl -w
    use strict;
    my %res;
    map {`smartctl -a $_` =~ /Reallocated_Sector_Ct(?:\D+(\d+)\D+){3}/ and $res{$_} = $1} grep !/part|usb/, </dev/disk/by-path/*>;
    
bjorn
()
Ответ на: комментарий от bjorn

Огромное спасибо за советы. Это как раз то, что нужно. Спасибо.

Shtsh ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.