Алгоритм взаимодействия apcupsd с системой при её выключении не менялся уже 17 лет. По умолчанию apcupsd запускается с ключом --kill-on-powerfail, что означает: при исчерпании заряда аккумулятора в ИБП, послать ИБП команду "уснуть" и одновременно запустить процедуру doshutdown из /usr/local/etc/apcupsd/apccontrol. В ИБП обычно предусмотрена задержка (так называемый grace delay) 10-40 секунд исполнения команд "выключиться" и "уснуть". В этом месте начинается race: что случится раньше, shutdown успеет корректно завершиться или ИБП выключится?
В прежние времена, наверное, это всех устраивало, потому что выключение системы проходило быстро и shutdown успевал всё завершить до выключения питания. Хотя напомню, что значение по умолчанию rcshutdown_timeout="90" заведомо больше grace delay любого ИБП. Так что race condition никуда не девался на самом деле.
В нынешнее время с распространением виртуальных машин во время выключения хоста включено время выключения виртуалок, которое может быть весьма значительным. Я например устаналиваю rcshutdown_timeout="240" и kern.init_shutdown_timeout="300" и то виндовые VM выключиться не успевают. Понятно, что в UPS grace delay не укладываемся точно.
Поэтому предлагаю новый алгоритм выключения системы посредством apcupsd, и открыл на эту тему ПР
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=237600 Суть нового (не очень нового, на самом деле, в Linux используется подобный) алгоритма:
Запускаем apcupsd с ключом --term-on-powerfail
apcupsd_enable="YES"
apcupsd_flags="--term-on-powerfail"
это значит после запуска процедуры shutdown и создания флага /var/run/powerfail apcupsd должен выйти и не путаться пока под ногами.
А в конце /etc/rc.shutdown вписываем строчку
test -f /var/run/powerfail && /usr/local/sbin/apcupsd --hibernateили
test -f /var/run/powerfail && /usr/local/sbin/apcupsd --power-off
(кому как удобнее, в зависимости от требуемого поведения ИБП после восстановления питания).
Это означает, что только после отработки всех rc.d скриптов с параметром stop в ИБП будет послана команда "уснуть" или "выключиться" соответственно.
UPD A brief summary in English.
My final conclusion. The default way apcupsd is started by the port (with --kill-on-powerfail) is wrong. You cannot rely on the UPS grace shutdown delay even with the default setting of rcshutdown_timeout="90", while using virtual machines necessitates making rcshutdown_timeout even longer. A race between the UPS grace delay and the FreeBSD shutdown procedure must be eradicated.
The only feasible way of doing it is:
1. Starting apcupsd with apcupsd_flags="--term-on-powerfail" so that the daemon exits once it has started the doshutdown procedure and does not send any commands to the UPS at this stage.
2. Putting the line
"test -f /var/run/powerfail && /usr/local/sbin/apcupsd --hibernate"or
"test -f /var/run/powerfail && /usr/local/sbin/apcupsd --power-off"
(depending on the desired behaviour of the UPS after the mains is restored) at the very end of the /etc/rc.shutdown script, after the "Insert other shutdown procedures here" line.
Thus the shutdown procedure started by "apcupsd --term-on-powerfail" can proceed at its own tempo, with "apcupsd --hibernate" being called when all the daemons and VMs have been safely shut down.
UPD 2. Ещё предлагают такой способ:
http://www.wfido.ru/m/RU.UNIX.BSD/grosbein.net+c3b53b4f который призван исключить достаточно маловероятную, но неприятную ситуацию, если питание успело восстановиться после завершения apcupsd, но до killpower.
Оригинал сообщения находится по адресу
https://victor-sudakov.dreamwidth.org/470378.html. Пожалуйста оставляйте комментарии там. Всего сейчас
комментариев.