16. Запуск getty на последовательных (и не только) консолях

Прим. перев.: Здесь и в дальнейшем автор использует термин «serial console». Точный перевод этого выражения на русский язык звучит как «консоль, подключаемая к последовательному порту». Однако, для краткости изложения, при переводе используется не вполне корректный, но хорошо знакомый администраторам жаргонизм «последовательная консоль». Также отметим, что в данном документе термины «консоль» и «терминал» используются как синонимы.
Прим. перев.: Принципы работы с шаблонами и экземплярами служб изложены в главе 10. Для лучшего понимания нижеприведенного материала, рекомендуется перечитать эту главу, если вы успели ее подзабыть.

Если вам лень читать всю статью целиком: для запуска getty на последовательной консоли достаточно указать в загрузчике параметр ядра console=ttyS0, и systemd автоматически запустит getty на этом терминале.

Физический последовательный порт RS-232, хотя уже и стал редкостью на современных настольных компьютерах, тем не менее, продолжает играть важную роль как на серверах, так и во встраиваемых системах. Он предоставляет простой и надежный доступ к управлению системой, даже когда сеть упала, а основной интерфейс управления завис. Кроме того, эмуляция последовательной консоли часто используется при управлении виртуальными машинами. Разумеется, в Linux уже давно реализована поддержка работы с последовательными консолями но, при разработке systemd, мы постарались сделать работу с ними еще проще. В этой статье я хочу рассказать о том, как в systemd реализован запуск getty на терминалах различных типов.
Для начала, хотелось бы отметить один важный момент: в большинстве случаев, чтобы получить приглашение к логину на последовательном терминале, вам не нужно совершать никаких дополнительных действий: systemd сам проверит настройки ядра, определит их них используемую ядром консоль, и автоматически запустит на ней getty. Таким образом, вам достаточно лишь правильно указать ядру соответствующую консоль (например, добавив к параметрам ядра в загрузчик console=ttyS0). Тем не менее, для общего образования все же стоит рассмотреть некоторые тонкости запуска getty в systemd. Эта задача решается двумя шаблонами юнитов:

* getty@.service отвечает за виртуальные консоли (virtual terminals, VT, известные в системе под именами /dev/tty1, /dev/tty2 и т.д.) — те, которые вы можете увидеть безо всякого дополнительного оборудования, просто переключившись на них из графического сеанса.
* serial-getty@.service обеспечивает поддержку всех прочих разновидностей терминалов, в том числе, подключаемых к последовательным портам (/dev/ttyS0 и т.д.). Этот шаблон имеет ряд отличий от getty@.service, в частности, переменная $TERM в нем устанавливается в значение vt102 (должно хорошо работать на большинстве физических терминалов), а не linux (которое работает правильно только на виртуальных консолях), а также пропущены настройки, касающиеся очистки буфера прокрутки (и поэтому имеющие смысл только на VT).

16.1 Виртуальные консоли
Рассмотрим механизм запуска getty@.service, обеспечивающий появление приглашений логина на виртуальных консолях (последовательные терминалы пока оставим в покое). По устоявшейся традиции, init-системы Linux обычно настраивались на запуск фиксированного числа экземпляров getty, как правило, шести (на первых шести виртуальных консолях, с tty1 по tty6). В systemd мы сделали этот процесс более динамичным: чтобы добиться большей скорости и эффективности, мы запускаем дополнительные экземпляры getty только при необходимости. Например, getty@tty2.service стартует только после того, как вы переключитесь на вторую виртуальную консоль. Отказавшись от обязательного запуска нескольких экземпляров getty, мы сэкономили немного системных ресурсов, а такжесделали загрузку системы чуть-чуть быстрее. При этом, с точки зрения пользователя, все осталось так же просто: как только он переключается на виртуальную консоль, на ней запускается getty, которая выводит приглашение к логину. Пользователь может и не подозревать о том, что до момента переключения приглашения не было. Тем не менее, если он войдет в систему и выполнит команду ps, он увидит, что getty запущены только на тех консолях, на которых он уже побывал.
По умолчанию, автоматический запуск getty производится на виртуальных консолях с первой по шестую, чтобы свести к минимуму отличия от привычной конфигурации (тем не менее, это поведение можно легко изменить, задавая параметр NAutoVTs= в файле logind.conf).
Отметим, что автоматический запуск getty на конкретной консоли производится только при условии, что эта консоль не занята другой программой. В частности, при интенсивном использовании механизма быстрого переключения пользователей графические сеансы могут занять первые несколько консолей. Чтобы такое поведение не заблокировало возможность запуска getty, мы предусмотрели специальную защиту, см. чуть ниже.
Две консоли играют особую роль: tty1 и tty6. tty1, при загрузке в графическом режиме, используется для запуска дисплейного менеджера, а при загрузке в многопользовательском текстовом режиме, systemd принудительно запускает на ней экземпляр getty, не дожидаясь переключений (в данном случае нет принципиальной разницы между принудительным запуском и запуском по запросу: первая консоль используется по умолчанию, так что запрос на ее активацию обязательно поступит.).
Что касается tty6, то она используется исключительно для автоматического запуска getty, и недоступна другим подсистемам, в частности, графическому серверу (при необходимости, вы можете легко поменять номер резервируемой консоли или отключить резервирование, используя параметр ReserveVT= в файле logind.conf). Мы сделали так специально, чтобы гарантировать возможность входа в систему в текстовом режиме, даже если графический сервер займет более пяти консолей.

16.2 Последовательные консоли
Работа с последовательными консолями и всеми остальными видами невиртуальных консолей реализована несколько иначе, чем с VT. По умолчанию, systemd запускает один экземпляр serial-getty@.service на основной консоли ядра (если для ядра настроен вывод в несколько консолей, основной считается та, которая идет первой в /sys/class/tty/console/active, т.е. указана последней в строке параметров ядра), если она не является виртуальной. Консоль ядра — это та консоль, на которую выводятся сообщения ядра. Обычно она настраивается в загрузчике, путем добавления к параметрам ядра аргумента наподобие console=ttyS050. Таким образом, если пользователь перенаправил вывод ядра на последовательную консоль, то по завершении загрузки он увидит на этой консоли приглашение для логина (отметим, что getty, а точнее, agetty на такой консоли вызывается с параметром -s, и поэтому не изменяет настроек символьной скорость (baud rate) — сохраняется то значение, которое было указано в строке параметров ядра.). Кроме того, systemd выполняет поиск консолей, предоставляемых системами виртуализации, и запускает serial-getty@.service на первой из этих консолей (/dev/hvc0, /dev/xvc0 или /dev/hvsi0). Такое поведение реализовано специальной программой-генератором — systemd-getty-generator. Генераторы запускаются в самом начале загрузки и автоматически настраивают различные службы в зависимости от соответствующих факторов.
В большинстве случаев, вышеописанного механизма автоматической настройки должно быть достаточно, чтобы получить приглашение логина там, где нужно — без каких-либо дополнительных настроек systemd. Тем не менее, иногда возникает необходимость в ручной настройке — например, когда необходимо запустить getty сразу на нескольких последовательных консолях, или когда вывод сообщений ядра направляется на один терминал, а управление производится с другого. Для решения таких задач достаточно определить по экземпляру serial-getty@.service для каждого последовательного порта, на котором вы хотите запустить getty:

После выполнения этих команд, getty будет принудительно запускаться для указанных последовательных портах при всех последующих загрузках.
В некоторых ситуациях может возникнуть необходимость в тонкой настройке параметров getty (например, заданная для вывода сообщений ядра символьная скорость непригодна для интерактивного сеанса). Тогда просто скопируйте штатный шаблон юнита в каталог /etc/systemd/system и отредактируйте полученную копию:

В приведенном примере создает файл настроек, определяющий запуск getty на порту ttyS2 (это определяется именем, под которым мы скопировали файл — serial-getty@ttyS2.service). Все изменения настроек, сделанные в данном файле, будут распространяться только на этот порт.
Собственно, это все, что я хотел рассказать о последовательных портах, виртуальных консолях и запуске getty на них. Надеюсь, рассказ получился интересным.

Содержание
Вперед - Работа с Journal
Назад - Сторожевые таймеры