Subversion Repositories vnag

Rev

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

  1. <?php
  2.  
  3. /*
  4.  * VNag - Nagios Framework for PHP
  5.  * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
  6.  * Licensed under the terms of the Apache 2.0 license
  7.  *
  8.  * Revision 2023-10-13
  9.  */
  10.  
  11. declare(ticks=1);
  12.  
  13. define('OUTPUT_UOM', 'MB');
  14. define('ROUND_TO', 0);
  15.  
  16. class OpenDeletedFilesCheck extends VNag {
  17.         protected $argDir = null;
  18.  
  19.         public function __construct() {
  20.                 parent::__construct();
  21.  
  22.                 $this->registerExpectedStandardArguments('Vhtwc');
  23.  
  24.                 $this->getHelpManager()->setPluginName('open_deleted_files');
  25.                 $this->getHelpManager()->setVersion('2023-10-13');
  26.                 $this->getHelpManager()->setShortDescription('This plugin checks for open deleted files (which require space but are not visible/accessible anymore).');
  27.                 $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
  28.                 $this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d directory] [-w warnSizeKB] [-c critSizeKB]');
  29.                 $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
  30.  
  31. #               $this->warningSingleValueRangeBehaviors[0]  = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
  32. #               $this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD;
  33.  
  34.                 // Individual (non-standard) arguments:
  35.                 $this->addExpectedArgument($this->argDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'directory', 'Directory to check (e.g. /tmp)Directory to check (e.g. /tmp)'));
  36.         }
  37.  
  38.         protected static function check_open_deleted_files($dir_to_check = '/') {
  39.                 // Note: Requires root
  40.                 exec('lsof -n', $lines, $ec);
  41.                 if ($ec != 0) return false;
  42.  
  43.                 /*
  44.                 $lines = explode("\n",
  45.                 'COMMAND     PID   TID TASKCMD               USER   FD      TYPE             DEVICE    SIZE/OFF       NODE NAME
  46.                 php-cgi     430                          oidplus    3u      REG               0,42           0 1502217042 /tmp/.ZendSem.uhCRtC (deleted)
  47.                 apache2     838                             root  150u      REG               0,42           0 1499023202 /tmp/.ZendSem.RFcTM9 (deleted)
  48.                 postgres   1060                      gitlab-psql  txt       REG                9,0     9291488   47189384 /opt/gitlab/embedded/postgresql/12/bin/postgres (deleted)
  49.                 php-cgi    1573                         owncloud    3u      REG               0,42           0 1499024339 /tmp/.ZendSem.2Qh70x (deleted)
  50.                 php-fpm7.  1738                             root    3u      REG               0,42           0  434907183 /tmp/.ZendSem.unGJqF
  51.                 php-fpm7.  1739                         www-data    3u      REG               0,42           0  434907183 /tmp/.ZendSem.unGJqF (deleted)
  52.                 php-fpm7.  1740                         www-data    3u      REG               0,42           0  434907183 /tmp/.ZendSem.unGJqF (deleted)
  53.                 runsvdir   1932                             root  txt       REG                9,0       27104   45351338 /opt/gitlab/embedded/bin/runsvdir (deleted)
  54.                 ');
  55.                 */
  56.  
  57.                 $line_desc = array_shift($lines);
  58.                 $p_name = strpos($line_desc, 'NAME');
  59.                 if ($p_name === false) return false;
  60.  
  61.                 $nodes = array();
  62.  
  63.                 foreach ($lines as $line) {
  64.                         if (trim($line) == '') continue;
  65.  
  66.                         $name = substr($line, $p_name);
  67.  
  68.                         preg_match('@.+\s(\d+)\$@ism', substr($line, 0, $p_name-1), $m);
  69.                         $tmp = rtrim(substr($line, 0, $p_name-1));
  70.                         $tmp = explode(" ", $tmp);
  71.                         $node = end($tmp);
  72.  
  73.                         $tmp = rtrim(substr($line, 0, $p_name-strlen($node)-1));
  74.                         $tmp = explode(" ", $tmp);
  75.                         $size = end($tmp);
  76.  
  77.                         if (substr($name, 0, strlen($dir_to_check)) !== $dir_to_check) continue;
  78.  
  79.                         if (strpos($name, ' (deleted)') === false) continue;
  80.                         if ($size == 0) continue;
  81.  
  82.                         $nodes[$node] = $size;
  83.                 }
  84.  
  85.                 $size_total = 0;
  86.                 foreach ($nodes as $node => $size) {
  87.                         $size_total += $size;
  88.                 }
  89.                 return $size_total;
  90.         }
  91.  
  92.         protected function cbRun($optional_args=array()) {
  93.                 $dir = $this->argDir->getValue();
  94.                 if (empty($dir)) $dir = '/';
  95.                 $dir = realpath($dir) === false ? $dir : realpath($dir);
  96.                 if (substr($dir,-1) !== '/') $dir .= '/';
  97.  
  98.                 $size = self::check_open_deleted_files($dir);
  99.                 if ($size === false) throw new VNagException("Cannot get information from 'lsof'");
  100.  
  101.                 $this->checkAgainstWarningRange( array($size.'B'), false, true, 0);
  102.                 $this->checkAgainstCriticalRange(array($size.'B'), false, true, 0);
  103.  
  104.                 $m = (new VNagValueUomPair($size.'B'));
  105.                 $m->roundTo = ROUND_TO;
  106.                 $sizeOut = $m->normalize(OUTPUT_UOM);
  107.  
  108.                 $msg = "$sizeOut opened deleted files in $dir";
  109.                 $this->setHeadline($msg);
  110.         }
  111. }
  112.