Запуск getty в NetBSD с помощью daemontools
Содержание
Введение
В NetBSD терминалы запускаются не при помощи rc-скриптов, а самим демоном init
, который руководствуется списком терминалов из файла /etc/ttys
. Первым делом заглянем в файл /etc/ttys
и посмотрим, какие терминалы включены по умолчанию:
console "/usr/libexec/getty Pc" wsvt25 off secure
constty "/usr/libexec/getty Pc" wsvt25 on secure
ttyE0 "/usr/libexec/getty Pc" wsvt25 off secure
ttyE1 "/usr/libexec/getty Pc" wsvt25 on secure
ttyE2 "/usr/libexec/getty Pc" wsvt25 on secure
ttyE3 "/usr/libexec/getty Pc" wsvt25 on secure
...
В четвёртой колонке находится переключатель, позволяющий включить или отключить указанный терминал. Если в колонке указан текст on
, то init
будет запускать соответствующий терминал, а в случае текста off
терминал запускаться не будет.
Существует концепция минимального демона инициализации, выдвинутая автором библиотеки musl libc Ричем Фелькером (Rich Felker), согласно которой минимальный процесс init должен лишь вызывать при запуске скрипт /etc/rc.init
, усыновлять осиротевшие процессы и вызывать скрипт /etc/rc.shutdown
при получении сигналов, инициирующих завершение работы. Эта концепция была воплощена в демоне sinit, исходные тексты которого распространяются проектом suckless.org, через репозиторий git.suckless.org/sinit/.
После настройки запуска консолей с помощью daemontools
становится возможным заменить init
из NetBSD на sinit
и получить операционную систему с простой и надёжной системой инициализации.
Ручная настройка сервиса
Создадим скрытый подкаталог, соответствующий имени консоли из первой колонки файла /etc/ttys
, в каталоге /service/
:
# mkdir /service/.constty/
Создадим внутри каталога сервиса файл run
со следующим содержимым::
#!/bin/sh
exec 2>&1
echo "Setting tty flags."
/sbin/ttyflags /dev/constty
exec \
/usr/libexec/getty Pc constty
И сделаем его исполняемым:
# chmod +x /service/.constty/run
Создадим каталог /service/.constty/log/
:
# mkdir /service/.constty/log/
Создадим внутри него скрипт run
со следующим содержимым::
#!/bin/sh
exec \
setuidgid multilog \
multilog t /var/log/constty/
И сделаем его исполняемым:
# chmod +x /service/.constty/log/run
Теперь создадим каталог /var/log/constty
, в котором multilog
будет вести журналы работы сервиса::
# mkdir /var/log/constty/
Установим пользователя и группу multilog
владельцами этого каталога:
# chown multilog:multilog /var/log/constty/
Отключим запуск getty
для constty
, поменяв переключатель on
на off
в четвёртой колонке строчки, соответствующей терминалу constty
в файле /etc/ttys
. Далее нужно найти с помощью команды ps
процесс getty
, связанный с этим терминалом, и завершить его при помощи команды kill
, после чего можно запустить getty
:
# mv /service/.constty /service/constty
Скрипт для настройки сервисов
Поскольку в NetBSD по умолчанию настроено четыре терминала, а мне предстояло перенастроить термианлы почти на десятке систем, то ручная перенастройка заняла бы сликом много времени. Я решил автоматизировать процесс перенастройки и написал скрипт для настройки терминалов:
#!/bin/sh
install_getty() {
SERVICE="$1"
DEVICE="$2"
mkdir -p /service/$SERVICE/log/
cat > /service/$SERVICE/run <<END
#!/bin/sh
exec 2>&1
echo "Setting tty flags."
/sbin/ttyflags /dev/$DEVICE
exec \\
/usr/libexec/getty Pc $DEVICE
END
cat > /service/$SERVICE/log/run <<END
#!/bin/sh
exec \\
setuidgid multilog \\
multilog t /var/log/$SERVICE/
END
chmod +x /service/$SERVICE/run
chmod +x /service/$SERVICE/log/run
mkdir -p /var/log/$SERVICE/
chown multilog:multilog /var/log/$SERVICE/
awk -v DEVICE="$DEVICE" '
{
if ($1 == DEVICE) {
match($0, /[\t ]on[\t ]/);
print substr($0, 1, RSTART) "off" substr($0, RSTART + 3, RSTART + RLENGTH - 1);
} else {
print $0;
}
}' /etc/ttys > /etc/ttys.new && \
cat /etc/ttys.new > /etc/ttys && \
rm /etc/ttys.new
}
install_getty constty constty
install_getty ttyE1 ttyE1
install_getty ttyE2 ttyE2
install_getty ttyE3 ttyE3
Остаётся только запустить этот скрипт на каждой из систем и завершить работу всех уже запущенных процессов getty
.