meta data for this page
  •  

2022-11-09 Unraid - проблема с переодическим lsof который вешает систему

На одном из домашних серверов установлен UNRAID. Недавно заметил такую особенность, когда снял с этого nas всю полезную нагрузку. Переодически раз в несколько минут запускается команда lsof которая повергает весь сервер в ступор.

Вызывается она с такими переменными:

sh -c LANG='en_US.UTF8' lsof -Owl /mnt/disk[0-9]* 2>/dev/null|awk '/^shfs/ && $0!~/\.AppleD(B|ouble)/ && $5=="REG"'|awk -F/ '{print $4}'

По-видимому это часть сбора статистики для веб интерфейса, которая написана привычным для unraid способом - “кое как лишь бы работало”. Вызывается эта строка из файла: /usr/local/emhttp/webGui/nchan/update_1

Вот полный листинг этого файла:

#!/usr/bin/php -q
<?PHP
/* Copyright 2005-2021, Lime Technology
 * Copyright 2012-2021, Bergware International.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
$docroot = '/usr/local/emhttp';
$varroot = '/var/local/emhttp';
require_once "$docroot/webGui/include/publish.php";
 
while (true) {
  unset($memory,$sys,$rpms,$lsof);
  exec("grep -Po '^Mem(Total|Available):\s+\K\d+' /proc/meminfo",$memory);
  exec("df /boot /var/log /var/lib/docker|grep -Po '\d+%'",$sys);
  exec("sensors -uA 2>/dev/null|grep -Po 'fan\d_input: \K\d+'",$rpms);
  $info = max(round((1-$memory[1]/$memory[0])*100),0)."%\0".implode("\0",$sys);
  $rpms = count($rpms) ? implode(" RPM\0",$rpms).' RPM' : '';
 
  $names = array_keys((array)parse_ini_file("$varroot/shares.ini"));
  exec("LANG='en_US.UTF8' lsof -Owl /mnt/disk[0-9]* 2>/dev/null|awk '/^shfs/ && \$0!~/\.AppleD(B|ouble)/ && \$5==\"REG\"'|awk -F/ '{print \$4}'",$lsof);
  $counts = array_count_values($lsof); $count = [];
  foreach ($names as $name) $count[] = $counts[$name] ?? 0;
  $count = implode("\0",$count);
 
  publish('update1', "$info\1$rpms\1$count");
  sleep(5);
}
?>

Cкорее всего этот скрипт считает количество открытых сессий к общим папкам для вывода этой информации на консоль в этом месте интерфейса:

Бесполезная трата ресурса. Я поискал записи на форуме unraid на предмет данной проблемы. Судя по всему она появилась достаточно давно и беспокоит только некоторых пользователей с нагруженными машинами, где lsof выполняется очень долго.

Для начала я попробовал исключить строку, вызывающую lsof из файла update_1. Это не принесло никакого результата, потому что видимо файл загружен в память и система работает с ним оттуда. После перезагрузки системные файлы заменяются файлами из образа, так как ОС работает с “золотым” образом который при старте системы загружается в память с USB диска.

В конце концов я заметил что процесс php работающий с данным файлов все еще запущен и убил его командой:

  pkill -f "/usr/bin/php -q /usr/local/emhttp/webGui/nchan/update_1" 

Затем я провел еще несколько наблюдений:

  • После перезагрузки системы скрипты update_1, update_2, update_3 не запускаются, пока пользователь не войдет в веб интерфейс и не откроет страницу “Dashboard”.
  • Скрипты продолжают отрабатывать в любом случае вне зависимости как пользователь покидает страницу.
  • Если убить скрипты командой killall /usr/bin/php - они не возвращаются никогда. Значит в системе есть какая-то проверка на успешность запуска этих скриптов, например PID файл.

Написал по этому поводу реплай в самой продвинутой ветке форума unraid.