Subversion Repositories vnag

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php /* <ViaThinkSoftSignature>mKTo94dd1u+i8HKvlQf3rPtiaEvY3sU5RuGBEWnFGFbKo1WomvGZiQ58cl1KqKOu6jf/DTuB6RmPuUku+7Y2oVS5IebUkUkt+TaXFBl7cUrOp9kkr8BjxTKDBkBvYTM6cGVUg9ceVBpDWkvmSvvkLCFabkOh8fmJsEifjyGrgIRjGCIhuY8DhwAjWz78+XosG/HnfYcf5Tpr6e/E7axGpEaVbBnb9otEG1CslG81GGDdlQp2/s35CqSMn3MBfL0qQxRwkvLHv5u345qDpgPmGL4mcK1bKQ7B4nNHFEn4qQQeuRPmZ1fLGrUHcmJGOH6Jy4hUMrnMe4yb9rpxxUPr6CHt0zI4QiW05pBTLwtQbmgRHll82LirDuSA27H4KtipGh+TuFMlZd1ixv7KcenO0YrVPU4SXV3XweaQT/luqLSVnajHVsXOIu4+FCCpV4AY07ppYtjbt9qbP6DcmbktbjiOFuHedAVC0L9448svSWHMDcOWdbAtpVhgajO9yTzMJblNvg558GrCR3YT+ol8SbU5h+iQCdPrtwETamtDGUw3p9kZIegGwbc6U+OjIbVnqKIPiNt13/4+uHcY8BZ+1BpGtPPfM1kR9c7yWkTJqkMEFFSp7ulsPfYN+pM66HFxMON8xQOOUv0tVST1rgey7KtE8/xzwLLjTIW3nZYoS9MPkTSqzijC8KYszhR0OohEYyQYle3+L2QTVd9ANakTCmKGhJ6t+dJeHzWXY/FFFeT019vVKTT03v51/olpUWV+/xs2joK9Dcb+ovTFvDQIMf3FTqlCCU1HOmj3F5wlvNJTZituEgo/9POFBmYdFSJnrX6JkPglDeJI7CmmPzxj+ZZxzaZjAOjAU4izd40N+xQx4RrI87++n44O7yBCv59UTrgIDEnhgKscQR9yMoMK5sSqKfbEaXk7L0un5evTgKeP3ZRvS2zftKWsbsEgd2zl0EjCZz599at2N4WawoWndSN0H1RyPLYncSJG6wS5QB9MgWt8SuUJMZfFJy4lETtstjdP5XQvz9VBbNAra3a+xRGzY8e4Z0JKzsV1jy2SDJ7cIQMW7Ci/NS2kghaKZl9T7CL+MITnbNeM2iPrQYYKSmnHxZi5keTqZ72Ahr6rB8Zck676pUX9AucqxT5+7Ox2QrP+IfuBnTDCCPavJ2MFAlCHp9bGdrjT6lcC1sfYdb1WlhYjqwbwXjMRsbg7NMhiaxSQ+Ozz/eJM83wgmo6Ql/4cFyhwqmKUj7d/d4q/q0TFh2Rh4uuYqpQeAZkAJHgXlJt8mZigOU9ieA0m6EhaEmr22N2Ac0Fgjr4qIbNTabu4Cd6Or4h8mZcwGBcE0/2zZZmQWNfn6hxpZ6/usd0fcQ==</ViaThinkSoftSignature> */ ?>
  2. <?php
  3.  
  4. /*
  5.  * VNag - Nagios Framework for PHP
  6.  * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
  7.  * Licensed under the terms of the Apache 2.0 license
  8.  *
  9.  * Revision 2018-11-04
  10.  */
  11.  
  12. declare(ticks=1);
  13.  
  14. class MdStatCheck extends VNag {
  15.         public function __construct() {
  16.                 parent::__construct();
  17.  
  18.                 if ($this->is_http_mode()) {
  19.                         // Don't allow the standard arguments via $_REQUEST
  20.                         $this->registerExpectedStandardArguments('');
  21.                 } else {
  22.                         $this->registerExpectedStandardArguments('Vhtv');
  23.                 }
  24.  
  25.                 $this->getHelpManager()->setPluginName('vnag_mdstat');
  26.                 $this->getHelpManager()->setVersion('2.0');
  27.                 $this->getHelpManager()->setShortDescription('This plugin checks the contents of /proc/mdstat and warns when a harddisk has failed.');
  28.                 $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
  29.                 $this->getHelpManager()->setSyntax('$SCRIPTNAME$ (no additional arguments expected)');
  30.                 $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
  31.         }
  32.  
  33.         private function getDisks($device) {
  34.                 $disks = glob("/sys/block/$device/md/dev-*");
  35.                 foreach ($disks as &$disk) {
  36.                         $ary = explode('/', $disk);
  37.                         $disk = substr(array_pop($ary), 4);
  38.                 }
  39.                 return $disks;
  40.         }
  41.  
  42.         private function raidLevel($device) {
  43.                 $level_file = "/sys/block/$device/md/level";
  44.                 if (!file_exists($level_file)) {
  45.                         throw new VNagException("Kernel too old to fetch RAID level of array $device");
  46.                 }
  47.                 $level = file_exists($level_file) ? trim(file_get_contents($level_file)) : 'RAID?';
  48.                 return $level;
  49.         }
  50.  
  51.         private function raidState($device) {
  52.                 $state_file = "/sys/block/$device/md/array_state";
  53.                 if (!file_exists($state_file)) {
  54.                         throw new VNagException("Kernel too old to fetch state of array $device");
  55.                 }
  56.                 $state = trim(file_get_contents($state_file));
  57.                 return $state;
  58.         }
  59.  
  60.         private function check_disk_state($array, $disk) {
  61.                 $disk_state_file = "/sys/block/$array/md/dev-$disk/state";
  62.                 if (!file_exists($disk_state_file)) {
  63.                         throw new VNagException("Kernel too old to fetch state of disk $array:$disk");
  64.                 }
  65.                 $disk_states = trim(file_get_contents($disk_state_file));
  66.                 $disk_state_ary = explode(',', $disk_states);
  67.                 $disk_state_ary = array_map('trim', $disk_state_ary);
  68.  
  69.                 $status = VNag::STATUS_OK;
  70.                 $verbosity = VNag::VERBOSITY_ADDITIONAL_INFORMATION;
  71.  
  72.                 foreach ($disk_state_ary as $disk_state) {
  73.                         // https://www.kernel.org/doc/html/v4.15/admin-guide/md.html
  74.                         // CRIT faulty: device has been kicked from active use due to a detected fault, or it has unacknowledged bad blocks
  75.                         // OK   in_sync: device is a fully in-sync member of the array
  76.                         // OK   writemostly: device will only be subject to read requests if there are no other options. This applies only to raid1 arrays.
  77.                         // CRIT blocked: device has failed, and the failure hasn.t been acknowledged yet by the metadata handler. Writes that would write to this device if it were not faulty are blocked.
  78.                         // WARN spare: device is working, but not a full member. This includes spares that are in the process of being recovered to
  79.                         // WARN write_error: device has ever seen a write error.
  80.                         // WARN want_replacement: device is (mostly) working but probably should be replaced, either due to errors or due to user request.
  81.                         // OK   replacement: device is a replacement for another active device with same raid_disk.
  82.  
  83.                         if (($disk_state == 'faulty') || ($disk_state == 'blocked')) {
  84.                                 $status = max($status, VNag::STATUS_CRITICAL);
  85.                                 $verbosity = min($verbosity, VNag::VERBOSITY_SUMMARY);
  86.                         }
  87.                         if (($disk_state == 'spare') || ($disk_state == 'write_error') || ($disk_state == 'want_replacement')) {
  88.                                 $status = max($status, VNag::STATUS_WARNING);
  89.                                 $verbosity = min($verbosity, VNag::VERBOSITY_SUMMARY);
  90.                         }
  91.                 }
  92.  
  93.                 return array($status, $verbosity, $disk_states);
  94.         }
  95.  
  96.         private function get_raid_arrays() {
  97.                 $arrays = array();
  98.                 $devices = glob('/dev/md/*');
  99.                 foreach ($devices as $device) {
  100.                         $ary = explode('/', $device);
  101.                         $arrays[] = 'md'.array_pop($ary);
  102.                 }
  103.                 return $arrays;
  104.         }
  105.  
  106.         protected function cbRun() {
  107.                 $disks_total = 0;
  108.                 $disks_critical = 0;
  109.                 $disks_warning = 0;
  110.  
  111.                 $arrays = $this->get_raid_arrays();
  112.                 foreach ($arrays as $array) {
  113.                         $level = $this->raidLevel($array);
  114.                         $state = $this->raidState($array);
  115.  
  116.                         $disk_texts = array();
  117.                         $verbosity = VNag::VERBOSITY_ADDITIONAL_INFORMATION;
  118.                         $disks = $this->getDisks($array);
  119.                         foreach ($disks as $disk) {
  120.                                 $disks_total++;
  121.                                 list($status, $verbosity_, $disk_states) = $this->check_disk_state($array, $disk);
  122.                                 $verbosity = min($verbosity, $verbosity_);
  123.                                 $this->setStatus($status);
  124.                                 if ($status == VNag::STATUS_WARNING) $disks_warning++;
  125.                                 if ($status == VNag::STATUS_CRITICAL) $disks_critical++;
  126.                                 $status_text = VNagLang::status($status, VNag::STATUSMODEL_SERVICE);
  127.                                 $disk_texts[] = "$disk ($status_text: $disk_states)";
  128.                         }
  129.  
  130.                         # Example output:
  131.                         # Array md0 (raid1, degraded): sda1 (Warning: faulty, blocked), sdb1 (OK: in_sync)
  132.                         $this->addVerboseMessage("Array $array ($level, $state): ".implode(', ', $disk_texts), $verbosity);
  133.                 }
  134.  
  135.                 $this->setHeadline(sprintf('%s disks in %s arrays (%s warnings, %s critical)', $disks_total, count($arrays), $disks_warning, $disks_critical));
  136.         }
  137. }
  138.