Задача


Сохранять историю состояний hdd и Logical drives с SAN хранилища IBM DS4700 на Zabbix server-е.

Исходные данные


  • IBM DS4700 с подключенным, хотя бы одним контроллером к локальной сети (для определенности, пусть IP одного из контроллеров будет 192.168.10.102, а второго -192.168.10.103)
  • установленный/настроенный Zabbix сервер(использовалась версия Zabbix-а 2.0.6)
  • сервер/выделенный компьютер (может выступать сам сервер Zabbix-а) с установленным Zabbix клиентом, который “неограниченно видит” по сети хотя бы один контроллер хранилища (делалось на CentOS release 6.4 (Final) с установленным perl (использовалась версия “revision 5 version 10 subversion 1”))
  • навыки работы в Linux системах
  • доступ к суппорт части ibm.com (необходима регистрация)

Методика решения


К сожалению, это оборудование IBM не имеет развитых средств мониторинга, необходимых для внедрения в ИТ-инфраструктуру организации. Посему, ход решения выглядит в виде:
  1. установка некоторого ПО, способного общаться с оборудованием из командной строки на станцию с агентом Zabbix
  2. расширение агента Zabbix через perl скрипты, которые будут парсить вывод данного ПО
  3. добавление в HOST на сервере Zabbix полученных, необходимых элементов данных(Items)

Решение


ПО, для общения с оборудованием

Выглядит в виде SMclient (версия 10.86.0G05.0035-1.noarch), который ставится после SMruntime (версия 10.86.0A05.0000-1.x86_64). Оба пакета входят в состав пакета дистрибутива Storage Manager (SM10.86_Linux_x64_Single-10.86.xx05.0035.tar\Linux_x64_10p86_single\Linux_x86-64\Linux_x64_10p86_single\Linux_x86-64\). Storage Manager берется с сайта ibm.com.
После установки, мы получим возможность из командной строки выполнять скрипты на DS4700 и получать вывод в локальную консоль:
  • информацию по HDD выведет команда /opt/IBM_DS/client/SMcli 192.168.10.102 192.168.10.103 -c "show allDrives;"
    Пример вывода
    Performing syntax check...
    
    Syntax check complete.
    
    Executing script...
    
    DRIVES------------------------------
    
    SUMMARY
       Number of drives: 48
          Current media type(s): Hard Disk Drive (48)
          Current interface type(s): Fibre (16), Serial ATA (SATA) (32)
    
       BASIC:
    
          TRAY, SLOT  STATUS   CAPACITY    MEDIA TYPE       INTERFACE TYPE  CURRENT DATA RATE  PRODUCT ID                                FIRMWARE VERSION  
          0, 1        Optimal  465.762 GB  Hard Disk Drive  SATA            4 Gbps             HUA721050KLA330      39M4557 42C0485IBM   GK6OAB4A          
          0, 2        Optimal  136.732 GB  Hard Disk Drive  Fibre           4 Gbps             MAX3147FD     F                           S708              
          0, 3        Optimal  136.732 GB  Hard Disk Drive  Fibre           4 Gbps             MAX3147FD     F                           S708              
          0, 4        Optimal  136.732 GB  Hard Disk Drive  Fibre           4 Gbps             MAX3147FD     F                           S708              
          0, 5        Optimal  136.732 GB  Hard Disk Drive  Fibre           4 Gbps             ST3146356FC   F                           B98A              
    ...
    

  • информацию по Logcal Drives выведет команда /opt/IBM_DS/client/SMcli 192.168.10.102 192.168.10.103 -c "show allLogicalDrives summary;"
    Пример вывода
    Performing syntax check...
    
    Syntax check complete.
    
    Executing script...
    
    STANDARD LOGICAL DRIVES SUMMARY
    Number of standard logical drives: 21
    
    
    NAME                STATUS   CAPACITY      RAID LEVEL  ARRAY       MEDIA TYPE       INTERFACE TYPE     
    APPDATA1            Optimal  224.000 GB    10          Array_04    Hard Disk Drive  Fibre channel      
    APPDATA3            Optimal  512.000 GB    10          Array_05    Hard Disk Drive  Serial ATA (SATA)  
    LDC01SAPPDAT1CL_Q1  Optimal  2.000 GB      10          Array_04    Hard Disk Drive  Fibre channel      
    MAILCLBASE          Optimal  164.000 GB    1           Array_16    Hard Disk Drive  Serial ATA (SATA)  
    MAILCLBASE0         Optimal  300.262 GB    1           Array_16    Hard Disk Drive  Serial ATA (SATA)  
    ...
    



Расширение агента Zabbix

  • Имеем два perl скрипта
    1. DS4700.Drive.state.pl — для определения состояния отдельных, физических HDD на сторэдже.
      Листинг
      #! /usr/bin/perl
      #ver - 1.0.5
      #скрипт определяющий состояние дисков со сторэджа DS4700 через утилиту /opt/IBM_DS/client/SMcli
      #с использованием кэшированного ответа с временм жизни $TTLCache секунд
      #
      #Входные параметры
      # -DiskID = идентификатор диска
      # -EnclosureID = идентификатор полки
      #Возвращаемые значения
      #-3 Replaced
      #-2 Object not found
      #-1 Unknown state
      ## 0 Failed
      ## 1 Optimal 
      #
      use Time::localtime;
      use File::stat;
      
      %vDisk_states = ();
      @vDiskState=();
      $vDiskID = "";
      $vEnclosureID = "";
      
      $FileCache='/tmp/zabbix.DS4700.Drive';
      $IBMSMcli='/opt/IBM_DS/client/SMcli';
      $DS4700Controllers='192.168.10.102 192.168.10.103';
      $TTLCache=120;
      
      $vTimeNow="";
      
      $Result = -2;
      
      $vSplitedText = "";
      $vSplitedDisksEncs = "";
      
      $vPart = "";
      
      for ($i=0;$i<=$#ARGV;$i++) {
      	if ( substr($ARGV[$i],0,1) eq '-' ){
      		if ($ARGV[$i]=~ m/DiskID/i){
      			if($i<$#ARGV){
      				if ( substr($ARGV[$i+1],0,1) ne '-' ){
      				$vDiskID=$ARGV[$i+1];
      				}
      			}
      		}
                      if ($ARGV[$i]=~ m/EnclosureID/i){
                              if($i<$#ARGV){
                                      if ( substr($ARGV[$i+1],0,1) ne '-' ){
                                      $vEnclosureID=$ARGV[$i+1];
                                      }
                              }
                      }
      	}
      }
      if (-e $FileCache){
      	$vFile_Cache_stats=stat($FileCache)->mtime;
      	$vTimeNow=time();
      		if ($vTimeNow-$vFile_Cache_stats>$TTLCache) {`$IBMSMcli $DS4700Controllers -c "show allDrives;">$FileCache`;}
      }else {`$IBMSMcli $DS4700Controllers -c "show allDrives;">$FileCache`;}
      
      @vStrings = `cat $FileCache`;
      
      if (defined(@vStrings)){ 
      	foreach (@vStrings)
      	{
      		@vSplitedText=split('      ',$_);
      		if ($_=~ m/BASIC/){$vPart='BASIC';}
      		if ($_=~ m/DRIVE CHANNELS/){
      			$vPart='DRIVE CHANNELS';
      		}
      		if ($_=~ m/DETAILS/){$vPart='DETAILS';}
      
      		if ($vPart eq 'BASIC'){
      			@vDiskState=();
      			if ($vSplitedText[1]=~ m/[0-9], [0-9]/){
      				@vDiskState=split(' ',$vSplitedText[2]);
      				$vDisk_states{$vSplitedText[1]}=$vDiskState[0];
      			}
      		}
      		if(defined($vDisk_states{$vEnclosureID.', '.$vDiskID})){
      			if ($vDisk_states{$vEnclosureID.', '.$vDiskID} eq 'Optimal'){$Result=1;}
      			if ($vDisk_states{$vEnclosureID.', '.$vDiskID} eq 'Replaced'){$Result=-3;}
              		if ($vDisk_states{$vEnclosureID.', '.$vDiskID} eq 'Failed'){$Result=0;}
      			if (($vDisk_states{$vEnclosureID.', '.$vDiskID} ne 'Optimal')&&($vDisk_states{$vEnclosureID.', '.$vDiskID} ne 'Replaced')&&($vDisk_states{$vEnclosureID.', '.$vDiskID} ne 'Failed')){
      				$Result=-1;
      			}
      		}
      	}
      }
      print("$Result");
      


      Пример использования:
      [root@XXXXXMonitor ~]# /etc/zabbix/scripts/DS4700.Drive.state.pl -EnclosureID 0 -DiskID 1 
      1
      

      Физический HDD за номером 1, который расположен в полке DS4700, имеющей ID=0, находится в состоянии 1 (Optimal).
    2. DS4700.Logical.state.pl — для определения состояния Logical Drives на сторэдже.
      Листинг
      #! /usr/bin/perl
      #ver - 1.0.1
      #скрипт определяющий состояние Logical Drives со сторэджа DS4700 через утилиту /opt/IBM_DS/client/SMcli
      #с использованием кэшированного ответа с временм жизни $TTLCache секунд
      #
      #Входные параметры
      # -LogicalID = идентификатор Logical Drive
      #Возвращаемые значения
      #-4 Degraded
      #-3 Degraded (Reconstruction)
      #-2 Object not found
      #-1 Unknown state
      ## 0 Failed
      ## 1 Optimal 
      #
      use Time::localtime;
      use File::stat;
      
      %vLogical_states = ();
      $vLogicalID = "";
      
      $FileCache='/tmp/zabbix.DS4700.Logical';
      $IBMSMcli='/opt/IBM_DS/client/SMcli';
      $DS4700Controllers='192.168.10.102 192.168.10.103';
      $TTLCache=120;
      
      $vTimeNow="";
      
      $Result = -2;
      
      $vSplitedText = "";
      
      $vPart = "";
      
      for ($i=0;$i<=$#ARGV;$i++) {
      	if ( substr($ARGV[$i],0,1) eq '-' ){
      		if ($ARGV[$i]=~ m/LogicalID/i){
      			if($i<$#ARGV){
      				if ( substr($ARGV[$i+1],0,1) ne '-' ){
      				$vLogicalID=uc($ARGV[$i+1]);
      				}
      			}
      		}
      	}
      }
      if (-e $FileCache){
      	$vFile_Cache_stats=stat($FileCache)->mtime;
      	$vTimeNow=time();
      		if ($vTimeNow-$vFile_Cache_stats>$TTLCache) {`$IBMSMcli $DS4700Controllers -c "show allLogicalDrives summary;">$FileCache`;}
      }else {`$IBMSMcli $DS4700Controllers -c "show allLogicalDrives summary;">$FileCache`;}
      
      @vStrings = `cat $FileCache`;
      
      if (defined(@vStrings)){ 
      	foreach (@vStrings)
      	{
       	if ($_=~ m/Script execution complete/){$vPart='END';}
                      if ($vPart eq 'NAME'){
                      @vSplitedText=split(/ {2,}/,$_);
      		#print("$vSplitedText[0]\n");
      		if($vSplitedText[0]=~ m/[0-9a-zA-Z_]+/){
      			$vLogical_states{uc($vSplitedText[0])}=$vSplitedText[1];}
      		}
      	if ($_=~ m/NAME                STATUS/){$vPart='NAME';}
      	}
      }
      if (defined($vLogical_states{$vLogicalID})){
      	if($vLogical_states{$vLogicalID} eq 'Optimal'){$Result=1;}
      	if($vLogical_states{$vLogicalID} eq 'Failed'){$Result=0;}
      	if($vLogical_states{$vLogicalID} eq 'Degraded (Reconstruction)'){$Result=-3;}
              if($vLogical_states{$vLogicalID} eq 'Degraded'){$Result=-4;}
      	if(($vLogical_states{$vLogicalID} ne 'Optimal')&&($vLogical_states{$vLogicalID} ne 'Failed')&&($vLogical_states{$vLogicalID} ne 'Degraded (Reconstruction)')&&($vLogical_states{$vLogicalID} ne 'Degraded')){$Result=-1;}
      }
      print($Result);
      


      Пример использования:
      [root@XXXXXMonitor ~]# /etc/zabbix/scripts/DS4700.Logical.state.pl -LogicalID LDC01SAPPDAT1CL_Q1
      1
      

      Logical Drive с именем LDC01SAPPDAT1CL_Q1, находится в состоянии 1 (Optimal).

  • Добавляем строки в конфиг Zabbix агента:
    UserParameter=DS4700.Drive.state[*],/usr/bin/perl /etc/zabbix/scripts/DS4700.Drive.state.pl -EnclosureID $1 -DiskID $2
    UserParameter=DS4700.Logical.state[*],/usr/bin/perl /etc/zabbix/scripts/DS4700.Logical.state.pl -LogicalID $1
    

  • Перезапускаем Zabbix агента.
  • Тестируем созданные элементы данных:
    [root@XXXXXMonitor ~]# zabbix_get -s 192.168.100.100 -k "DS4700.Drive.state[0,1]"
    1
    

    [root@XXXXXMonitor ~]# zabbix_get -s 192.168.100.100 -k "DS4700.Logical.state[LDC01SAPPDAT1CL_Q1]"
    1
    

    где, 192.168.100.100 — сервер/выделенный компьютер с установленным Zabbix клиентом


Добавление новых элементов данных на сервере Zabbix

Ничем не отличается от добавления стандартного элемента данных, за исключением ключа данных, который будет выглядеть, для приведенного выше примера, как DS4700.Drive.state[0,1] и DS4700.Logical.state[LDC01SAPPDAT1CL_Q1].