ВАЛЕНТИН СИНИЦЫН
Крепкий орешек NUT
Как известно, защитой от некачественного электропитания может служить только качественный UPS. Однако даже танковый аккумулятор не стоит ровным счетом ничего, если он не способен вовремя остановить систему. Здесь на помощь приходит инструментарий NUT.
Традиционно для управления ИБП применяются штатные утилиты, разработанные производителем оборудования. Зачастую они доступны не только для Windows, но и для UNIX, Linux и других систем. Хотя эти инструменты можно назвать кроссплатформенными в формальном смысле этого слова, нередко они несут на себе «отпечаток» той ОС, для которой были созданы изначально. Как правило, это программы с графическим пользовательским интерфейсом, что делает их малопригодными для запуска в режиме демона, к которому привыкли администраторы UNIX. Более того, и сама графическая среда X Window устанавливается на сервер далеко не всегда. Об очевидных проблемах совместимости (производитель может не предоставлять ни пакеты для вашего любимого дистрибутива, ни исходные тексты для самостоятельной сборки) не стоит и говорить. Выходом из сложившейся ситуации может стать использование открытых решений, об одном из которых – Network UPS Tools (NUT) версии 2.0 – мы и поговорим подробнее.
Что подразумевает собой понятие «настройка ИБП»? В первую очередь, это обеспечение корректного останова ОС при истощении аккумуляторных батарей и последующий автоматический запуск компьютера после восстановления электропитания. Во-вторых, это наблюдение за такими параметрами состояния ИБП, как режим работы («от сети» или «от батарей»), степень разряда АКБ, входное и выходное напряжение, температура, а также мощность нагрузки. В последнем случае фатальными могут оказаться как слишком большие, так и слишком маленькие значения, о чем будет сказано чуть позже.
Прежде чем переходить к использованию NUT, давайте вкратце рассмотрим его внутреннее устройство.
Мониторинг ИБП изнутри
В терминологии NUT программный код, отвечающий за непосредственное взаимодействие с оборудованием, называется «драйвер ИБП» (UPS driver). Следует, однако, понимать, что этот драйвер существенно отличается от драйверов традиционных устройств: сетевых и звуковых карт, клавиатур, «мышей» и т. п. Последние выполняются в режиме ядра и используют его API для передачи сообщений приложениям. В свою очередь драйвер ИБП – обычная программа, имеющая интерфейс командной строки и периодически запрашивающая характеристики ИБП через соответствующее устройство в файловой системе. Например, /dev/ttySx для UPS, подключенного к последовательному порту в системе Linux или /dev/usb/hid/hiddev/x для устройств, управляющихся через USB. Драйвер ИБП инкапсулирует в себе протокол, который поддерживает UPS и напрямую используется крайне редко. Его основная задача – привести данные, полученные от ИБП в стандартный формат и передать их демону upsd через сокет UNIX, расположенный в каталоге statedir (см. ниже) для последующей обработки. Сам upsd не предпринимает никаких активных действий, но выполняет роль диспетчера сообщений, транслирующего все необходимые сведения по запросу многочисленных клиентов, которые могут быть установлены как в локальной, так и на удаленной системе. Именно upsd поддерживает списки контроля доступа (ACL) и определяет, кто сможет наблюдать за выделенным ИБП, а кто – нет.
Клиенты – самое высокоуровневое приложение в номенклатуре NUT. Среди них есть непрерывно наблюдающие за «здоровьем» ИБП (upsmon), обеспечивающие доступ к считыванию и изменению параметров UPS через интерфейс командной строки (upsc/upscmd) или через Web (upstats/upset), планировщики (upssched) и даже графические утилиты: KNutClient (http://www.alo.cz/knutclient), WMNut (http://wmnut.mgeups.org).
Таким образом, для настройки ИБП необходимо выбрать соответствующий драйвер (NUT 2.0 поддерживает изделия около 25 различных производителей, в том числе APC, Powercom, MGE, Ippon, и др.), назначить списки контроля доступа для upsd и подготовить один или более клиентов. Обязательным минимумом является upsmon, который и будет останавливать систему в случае разряда батарей. Рекомендуется также обеспечить средства для мониторинга параметров ИБП: upsc, upstat/upset и т. д.
Однако прежде чем произвести упомянутые выше действия, NUT необходимо установить в вашу систему. Наиболее общим способом является сборка из исходных текстов, и поэтому мы поговорим о ней подробнее.
Собираем собственную версию NUT
Прежде чем браться за компиляцию NUT, проверьте, существует ли для вашей системы готовый пакет (http://eu1.networkupstools.org/packages.html). Если таковой имеется, убедитесь, что в него включен драйвер для вашей модели ИБП (учтите, что один драйвер может поддерживать несколько различных устройств). Если нужный драйвер отсутствует, вам все же придется произвести самостоятельную сборку, но вы сможете использовать spec-файлы RPM, build-сценарии и прочие подобные вещи, чтобы не нарушить пакетную базу данных вашего дистрибутива.
Загрузите архив nut-2.0.x.tar.gz с сайта http://www.net-workupstools.org и распакуйте его в любой подходящий каталог. NUT использует стандартную среду autoconf/automake, и его сборка может быть выполнена привычной последовательностью команд:
# ./configure <параметры> && make && make install
Среди полезных параметров сценария configure назовем:
- --prefix – задает общий «корень» для всего дерева директорий NUT. Значением по умолчанию является /usr/local/ups, но вы можете выбрать другой путь, например, /usr/local или /usr, чтобы установить NUT в общесистемные каталоги (исполняемые файлы – в /usr/bin вместо /usr/local/ups/bin и т. д.).
- --with-statepath – задает каталог для хранения сокетов UNIX, создаваемых драйверами и другой информации о состоянии. Значение по умолчанию – /var/state/ups. Пользователь, от имени которого работает NUT (см. ниже), должен иметь право чтения/записи на эту директорию.
- --with-port – указывает TCP-порт, используемый, в частности, демоном upsd для приема входящих соединений. По умолчанию NUT 2.0 использует порт 3493, а более ранние (несовместимые) версии – 3305.
- --with-user – задает пользователя, от имени которого будут выполняться демоны NUT. Значение по умолчанию – nobody. При желании вы (или разработчики дистрибутива) можете создать для NUT специальную учетную запись и группу, например, nut:nut.
- --with-drivers – здесь указывается список драйверов ИБП, подлежащих сборке. В подавляющем большинстве случаев необходимо выбрать лишь один из них.
Более подробную информацию можно найти в файле docs/configure.txt в архиве с исходными текстами NUT. После выполнения configure наберите «make» и «make install» (от имени root), чтобы завершить сборку и установку. Для создания шаблонов конфигурационных файлов используйте «make install-conf». Помимо этого, не забудьте создать каталог для хранения сокетов (statepath) и назначить ему необходимые права доступа (0700, владелец nut:nut, где «nut» – пользователь, от имени которого будут выполняться демоны). Подробности ищите в файле INSTALL, включенном в стандартный комплект поставки.
Запускаем NUT
В данном разделе мы рассмотрим настройку NUT в самом простом случае, когда имеется один ИБП, подключенный к одному компьютеру. В принципе NUT способен поддерживать и более сложные системы, когда один UPS контролирует несколько машин. В такой ситуации компьютер, к которому подключен ИБП, является главным (master) и отвечает за своевременное оповещение и выключение подчиненных (slave) систем.
Конфигурационные файлы NUT хранятся в каталоге /etc. Если на предыдущем этапе вы выполнили команду «make install-conf», то сейчас сможете воспользоваться шаблонами, сохраненными в файлах *.sample.
Первый файл, в который вам предстоит внести изменения, называется ups.conf. Он определяет все параметры подключенных к вашему компьютеру ИБП, а также задает некоторые глобальные опции, например, учетную запись, от имени которой будут выполняться драйверы (директива user) и интервал опроса оборудования (директива pollinterval).
Листинг 1. Пример файла ups.conf
user = nut
[ups0]
driver = ippon
port = /dev/ttyS0
desc = "Server UPS"
Данный файл определяет один источник бесперебойного питания, имеющий имя «ups0» и подключенный к первому последовательному порту (/dev/ttyS0). Поле «desc» является необязательным и задает текстовую строку-описание для ИБП. Поле «driver» определяет название драйвера, который будет использоваться для связи с UPS. В данном случае используется ippon, универсальный драйвер для всех ИБП одноименного производителя. Поля «driver» и «port» должны присутствовать в каждой секции файла ups.conf. Руководство пользователя NUT также рекомендует удостовериться, что файл устройства (в нашем примере /dev/ttyS0) не доступен ни для кого, кроме пользователя «nut». После того как файл ups.conf создан, вы можете проверить его корректность, загрузив драйвер ИБП. Для этого используется утилита upsdrvctl, расположенная в каталоге /bin.
# upsdrvctl start
Если все пойдет гладко, утилита отрапортует об успешном обнаружении ИБП и перейдет в фоновый режим. В противном случае будет выдано сообщение об ошибке. Проверьте, правильно ли заполнены поля driver и port, а также удостоверьтесь, что выбранный вами драйвер не требует указания дополнительных параметров. Если таковые имеются, добавьте их в соответствующую секцию ups.conf. Другой распространенной проблемой является невозможность создания файлов в каталоге statepath при работе от имени пользователя, указанного директивой «user» в файле ups.conf (или параметром --with-user сценария configure, если таковая отсутствует). Теперь, когда в вашей системе имеется новый фоновый процесс, собирающий информацию о состоянии ИБП, настало время подумать и о том, как эту информацию получать. В первую очередь необходимо настроить демон upsd, поскольку, как мы помним, именно он отвечает за передачу этих данных приложениям-клиентам.
Конфигурация upsd сводится к построению списков контроля доступа (ACL), которые сохраняются в файле /upsd.conf.
Листинг 2. Пример файла upsd.conf
ACL local 127.0.0.1/32
ACL all 0.0.0.0/0
ACCEPT local
REJECT all
Данный файл определяет два ACL-списка: «local» (127.0.0.1/32) и «all» (все узлы Сети). Директива ACCEPT предписывает upsd принимать соединения с локального хоста, а директива REJECT – пресекать любые попытки связи с узлов «all». Upsd просматривает эти директивы в порядке перечисления до тех пор, пока не будет найдено совпадение, поэтому можно быть уверенным, что наш ИБП будет «виден» только с компьютера, к которому он подключен. На мой взгляд, для мониторинга ИБП с других машин удобнее использовать SSH-соединение или веб-интерфейс, а не прямое подключение к демону upsd.
Далее, необходимо создать файл /upsd.users, в котором будут перечислены учетные записи пользователей, обладающих правами администратора. Администраторы могут изменять переменные состояния драйверов и подавать команды ИБП (например, «выключить звуковое оповещение»).
Листинг 3. Пример файла upsd.users
[admin]
password = my_passwd
allowfrom = local
actions = set
instcmds = all
upsmon master
Каждому пользователю соответствует отдельная секция файла upsd.users. В данном случае мы определили учетную запись «admin» с паролем «my_passwd» (обратите внимание, что он хранится в открытом виде), разрешили доступ с узлов из списка «local» и предоставили право устанавливать значения переменных (actions = set) и выполнять любые команды (instcmds = all). Более полное описание формата upsd.users можно найти в соответствующем разделе руководства man.
Поскольку файлы upsd.conf и upsd.users содержат конфиденциальную информацию в незашифрованной форме, следует ограничить доступ к ним:
# chown root:nut upsd.conf upsd.users
# chmod 0640 upsd.conf upsd.users
Теперь все готово к тому, чтобы запустить демон upsd.
# /sbin/upsd
Если запуск прошел нормально (о чем свидетельствует переход upsd в фоновый режим), вы можете наконец-то выполнить программу-клиент. В качестве «пробы пера» хорошо подойдет upsc, простая утилита, входящая в состав NUT и позволяющая просматривать текущие параметры состояния ИБП.
# upsc ups0@localhost
battery.charge: 97.1
battery.voltage: 13.5
driver.name: ippon
driver.parameter.port: /dev/ttyS0
driver.version: 2.0.0
driver.version.internal: 0.02
input.frequency: 50.1
input.voltage: 208.3
output.voltage: 209.4
ups.load: 012
ups.mfr: Ippon
ups.model: universal driver
ups.status: OL
ups.temperature: 25.0
|
Здесь ups0 – название вашего ИБП, указанное в файле ups.conf, а localhost – имя узла, на котором запущен демон upsd. Вы можете видеть различные параметры состояния:
- заряд батарей (battery.charge);
- температуру (battery.temperature);
- режим работы (ups.status: OL означает «on-line/от сети», OB – «on battery/от батарей», LB – «low battery/батареи разряжены»);
- входное и выходное напряжение (input.voltage, output. voltage).
Полный список характеристик зависит от драйвера ИБП.
Удостоверившись в работоспособности данной конфигурации, можно приступать к настройке upsmon – центрального клиентского демона, обеспечивающего реакцию системы на сигналы ИБП.
Останов системы
В режиме работы от батарей, перед самым их истощением, ИБП генерирует сообщение «battery low». Upsmon получает и обрабатывает этот сигнал, вызывая команду «shutdown -h now» или подобную ей для корректной остановки системы. Более детально данный процесс можно описать следующей схемой:
- ИБП генерирует событие «battery low».
- Upsmon получает данный сигнал и инициирует выключение:
- создается специальный файл POWERDOWNFLAG, являющийся признаком того, что система находится в режиме отключения в связи с истощением батарей ИБП;
- выполняется команда SHUTDOWNCMD;
- rc-сценарий использует проверку флага POWER-DOWNFLAG для предотвращения «энергетической гонки» (power race).
Все упомянутые выше параметры задаются в файле /upsmon.conf, который может иметь следующий вид:
Листинг 4. Пример файла upsmon.conf
MONITOR ups0@localhost 1 admin my_passwd master
RUN_AS_USER nut
POWERDOWNFLAG /killpower
SHUTDOWNCMD "/sbin/shutdown -h now"
Замечание. Внимательный читатель может спросить: хватит ли у демона upsmon, выполняющегося от имени поль-зователя RUN_AS_USER (в нашем примере – nut) прав на запуск команды «shutdown»? Да, поскольку во время старта upsmon специально «резервирует» для этих целей процесс, работающий с привилегиями суперпользователя. Угроза для безопасности системы здесь невелика, поскольку сетевое взаимодействие и прочая активность upsmon происходит в другом процессе. При возникновении критической ситуации непривилегированный процесс-потомок сообщает об этом «дремлющему» родителю, который и выполняет команду SHUTDOWNCMD.
Директива MONITOR задает ИБП, за которым будет наблюдать upsmon (в нашем примере – ups0@localhost) и реквизиты пользователя. Поскольку последние содержатся в файле upsmon.conf в открытом виде, необходимо снова позаботиться об ограничении доступа (см. выше).
«Энергетической гонкой» называется ситуация, когда ИБП переходит в режим работы от сети вскоре после генерации сигнала «battery low», в процессе останова системы. В этом случае компьютер, настроенный на автоматическое включение после сбоя электропитания (см. раздел «Аппаратные аспекты») окажется заложником собственной «осторожности», ведь фактически никакого сбоя не произойдет! Мне приходилось слышать, что некоторые модели UPS разрешают данную проблему автоматически, однако, «во избежание» предлагаю вам использовать следующий механизм, обеспечивающий корректную работу системы даже в случае «глупого» ИБП (см. листинг 5):
- В начале своего выполнения rc-сценарий, отвечающий за останов системы (/etc/rc.d/halt, rc.halt и т. п.) проверяет наличие флага POWERDOWNFLAG.
- Если флаг присутствует, сценарий выполняет все действия, необходимые для корректного завершения работы (выгружает демоны, размонтирует файловые системы и т. п.), после чего засыпает на непродолжительное время, например на 2-3 минуты.
- Если по истечении этого времени rc-сценарию вернулось управление (т.е. компьютер остался включенным, несмотря на то, что батареи ИБП истощены), мы подозреваем «энергетическую гонку» и принудительно перезагружаем систему.
Для проверки флага лучше использовать не стандартные средства bash (оператор -f), а специальный параметр командной строки утилиты upsmon, -K. В данном случае код завершения upsmon будет равен EXIT_SUCCESS (0), если флаг присутствует и EXIT_FAILURE в противном случае. Это обеспечивает более надежное функционирование сценария.
Листинг 5. rc-сценарий, обеспечивающий защиту от power race
/usr/local/ups/sbin/upsmon -K >/dev/null 2>&1
if [ $? = 0 ]; then
KILLPOWER=1
else
KILLPOWER=0
fi
# ...размонтирование ФС, останов демонов
if [ $KILLPOWER = 1 ]; then
echo "Swithching UPS off, please wait"
/usr/local/ups/bin/upsdrvctl shutdown
sleep 120
# Power-race workaround
echo “Hmm... Still alive?!”
reboot -d -f -i
fi
В рамках одной статьи сложно осветить все возможности такого богатого инструмента, как NUT. «За бортом» остались и веб-приложения, и поддержка SSL, и многие другие вопросы. Однако, я надеюсь, изложенных здесь сведений будет достаточно, чтобы понять, нужен ли вам NUT, получить представление о его архитектуре и базовые навыки конфигурирования. За более подробной информацией вы всегда сможете обратиться к страницам руководства и справочной документации, распространяющимися вместе с исходными текстами NUT. Успехов!
Приложение
Аппаратные аспекты
Непосредственное подключение UPS к системному блоку, как правило, не вызывает затруднений и подробно описывается в документации к оборудованию. Проблема состоит в другом: как настроить компьютер таким образом, чтобы он не только корректно выключался, но и автоматически включался?
С точки зрения компьютера (не операционной системы!), истощение батарей ИБП есть сбой электропитания (UPS просто перестает генерировать выходное напряжение, как только процент разрядки превысит некоторый критический порог). Современные версии BIOS позволяют настроить реакцию системы на события такого рода. Соответствующая опция обычно называется «After power fail» или подобным образом и может быть найдена в самых различных подменю. Заводская установка – «Off» означает «требуется ручное включение». Измените ее на «On», и тогда компьютер будет автоматически включаться при появлении напряжения на входных клеммах блока питания. Поскольку ИБП, переходя в режим работы «от сети», сразу же подает ток на все обслуживаемые устройства, от администратора больше не требуется никаких настроек.
Другим важным аспектом является мощность нагрузки. Памятуя поговорку «все крайности плохи», можно сказать, что здесь опасна как перегрузка, так и «недогрузка». С первой из них все понятно: подключение к ИБП лазерного принтера, утюга или электрочайника приведет к срабатыванию предохранителя и немедленному отключению потребителей тока. Никакого сигнала «battery low» в данном случае сгенерировано не будет, так что upsmon, upsd и прочие окажутся бесполезными.
Как это ни удивительно, «недогрузка» зачастую грозит теми же последствиями. В некоторые ИБП встраивается так называемая «зеленая функция» (green function), предотвращающая работу на холостом ходу при малой внешней нагрузке. Опыт показывает, что ИБП Ippon Back Power Pro 400 не замечает «народный сервер» Celeron-600/256 RAM/HDD без монитора. Симптомы, свидетельствующие о срабатывании «зеленой функции», таковы: слишком малое время работы от аккумулятора (5-10 минут), несмотря на то, что подключенный к ИБП компьютер имеет небольшую мощность; некорректный останов ОС при условии наличия правильно настроенной системы слежения (NUT или подобной). Для устранения «неполадки» можно обратиться в сервисный центр или же решить проблему с другого конца – повысить общую мощность, например, подключив к компьютеру дополнительные жесткие диски.