From e66acaaf2894893316cdd7cc5256109c083c9d0b Mon Sep 17 00:00:00 2001 From: nnz1024 <0comffdiz@inbox.ru> Date: Sun, 28 Oct 2012 03:50:00 +0400 Subject: [PATCH] Version v13.1 (2012-10-28 03:50) [AUTO] --- s4a.tex | 361 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) diff --git a/s4a.tex b/s4a.tex index de53318..bf21800 100644 --- a/s4a.tex +++ b/s4a.tex @@ -3328,6 +3328,367 @@ StartLimitAction=reboot-force \href{http://www.pengutronix.de/}{Pengutronix}, которым приндалежит основная заслуга реализации сторожевого контроля в systemd. +\section{Запуск getty на последовательных (и не~только) консолях} + +\emph{Если вам лень читать всю статью целиком: для запуска getty на +последовательной консоли\footnote{Прим. перев.: Здесь и в дальнейшем автор +использует термин <>. Точный перевод этого выражения на русский +язык звучит как <<консоль, подключаемая к последовательному порту>>. Однако, +для краткости изложения, при переводе используется не~вполне корректный, но +хорошо знакомый администраторам жаргонизм <<последовательная консоль>>. Также +отметим, что в данном документе термины <<консоль>> и <<терминал>> используются +как синонимы.} достаточно добавить параметр ядра \verb+console=ttyS0+, и systemd +автоматически запустит getty на этом терминале.} + +Физический последовательный порт +\href{https://ru.wikipedia.org/wiki/RS-232}{RS-232}, хотя уже и стал редкостью +на современных настольных компьютерах, тем не~менее, продолжает играть +важную роль на современных серверах и встраиваемых системах. Он предоставляет +простой и надежный доступ к управлению системой, даже когда сеть упала, а +основной интерфейс управления завис. Кроме того, эмуляция последовательной +консоли часто используется при управлении виртуальными машинами. + +Разумеется, в Linux уже давно реализована поддержка работы с последовательными +консолями, однако при разработке +\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} мы постарались +сделать работу с ними еще проще. В этой статье я хочу рассказать о том, как в +systemd реализован запуск \href{https://ru.wikipedia.org/wiki/Getty}{getty} на +терминалах различных типов. + +Для начала, хотелось бы отметить следующий момент: в большинстве случаев, чтобы +получить приглашение к логину на последовательном терминале, вам не~нужно +совершать никаких дополнительных действий: systemd сам проверит настройки ядра, +определит их них используемую ядром консоль, и автоматически запустит на ней +getty. Таким образом, вам достаточно лишь правильно указать ядру соответствующую +консоль (например, добавив к параметрам ядра в загрузчик +console=ttyS0+). + +Тем не~менее, для общего образования мы все же рассмотрим некоторые тонкости +запуска getty в systemd. Эта задача решается двумя шаблонами +юнитов\footnote{Прим. перев.: Принципы работы с шаблонами и экземплярами служб +изложены в главе~\ref{sec:instances}. Для лучшего понимания нижеприведенного +материала, рекомендуется перечитать эту главу, если вы ее подзабыли.}: +\begin{itemize} + \item +getty@.service+ отвечает за + \href{https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C}% + {виртуальные консоли} (+/dev/tty1+ и т.д.)~--- их можно увидеть + безо всякого дополнительного оборудования, просто переключившись + на них из графического сеанса. + + \item +serial-getty@.service+ обеспечивает поддержку всех прочих + разновидностей терминалов, в том числе, подключаемых к + последовательным портам (+/dev/ttyS0+ и т.д.). Этот шаблон имеет + ряд отличий от +getty@.service+, в частности, переменная \verb+$TERM+ + в нем устанавливается в значение +vt102+ (должно хорошо работать + на большинстве физических терминалов), а не~+linux+ (которое + работаеть правильно только на виртуальных консолях), а также + пропущены настройки, касающиеся очистки буфера прокрутки (и + поэтому имеющие смысл только на VT). +\end{itemize} + +\subsection{Виртуальные консоли} + +Рассмотрим механизм запуска +getty@.service+, обеспечивающий появление +приглашений логина на виртуальных консолях (последовательны терминалы пока +оставим в покое). По устоявшейся традиции, init-системы Linux обычно +настраивались на запуск фиксированного числа экземпляров getty, как правило, +шести (на первых шести виртуальных консолях, с +tty1+ по +tty6+). + +В systemd мы сделали этот процесс более динамичным: чтобы добиться большей +скорости и эффективности, мы запускаем дополнительные экземпляры getty только +при необходимости. Например, +getty@tty2.service+ стартует только после того, +как вы переключитесь на вторую виртуальную консоль. Отказавшись от +обязательного запуска нескольких экземпляров getty, мы сэкономили немного +системных ресурсов, а также сделали загрузку системы чуть-чуть быстрее. При +этом, с точки зрения пользователя, все очень просто: как только он переключается +на виртуальную консоль, на ней запускается getty, которая выводит приглашение к +логину. Пользователь может и не~подозревать о том, что до момента переключения +ничего этого не~было. Тем не~менее, если он войдет в систему и выполнит команду ++ps+, он увидит, что getty запущены только на тех консолях, на которых он уже +побывал. + +По умолчанию, автоматический запуск getty производится на виртуальных консолях с +первой по шестую (чтобы свести к минимуму отличия от привычной +конфигурации)\footnote{Тем не~менее, это поведение можно легко изменить, +задавая параметр +NAutoVTs=+ в файле +\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.} +Отметим, что автоматический запуск getty на конкретной консоли производится +только при условии, что эта консоль не~занята другой программой. В частности, +при интенсивном использовании механизма +\href{https://en.wikipedia.org/wiki/Fast_user_switching}{быстрого переключения +пользователей} графические сеансы могут занять первые несколько консолей (чтобы +такое поведение не~заблокировало возможность запуска getty, мы предусмотрели +специальную защиту, см. чуть ниже). + +Две консоли играют особую роль: +tty1+ и +tty6+. +tty1+, при загрузке в +графическом режиме, используется для запуска дисплейного менеджера, а при +загрузке в многопользовательском текстовом режиме, systemd принудительно +запускает на ней экземпляр getty, не~дожидаясь переключений\footnote{В данном +случае нет принципиальной разницы между принудительным запуском и запуском по +запросу: первая консоль используется по умолчанию, так что запрос на ее +активацию обязательно поступит.}. + +Что касается +tty6+, то она используется исключительно для автоматического +запуска getty, и недоступна другим подсистемам, в частности, графическому +серверу\footnote{При необходимости, вы можете легко поменять резервируемую +консоль, используя параметр +ReserveVT=+ в файле +\href{http://www.freedesktop.org/software/systemd/man/logind.conf.html}{logind.conf}.} +Мы сделали так специально, чтобы гарантировать возможность входа в систему в +текстовом режиме, даже если графический сервер займет более пяти консолей. + +\subsection{Последовательные консоли} + +Работа с последовательными консолями (и всеми остальными видами не-виртуальных +консолей) реализована несколько иначе, чем с VT. По умолчанию, systemd запускает +один экземпляр +serial-getty@.service+ на основной консоли ядра\footnote{Если +для ядра настроен вывод в несколько консолей, \emph{основной} считается та, которая +идет \emph{первой} в +/sys/class/tty/console/active+, т.е. указана +\emph{последней} в строке параметров ядра.} (если она не~является виртуальной). +Консолью ядра~--- это та консоль, на которую выводятся сообщения ядра. Обычно +она настраивается в загрузчике, путем добавления к параметрам ядра аргумента +наподобие +console=ttyS0+\footnote{Подробнее об этой опции см. в файле +\href{https://www.kernel.org/doc/Documentation/kernel-parameters.txt}{kernel-parameters.txt}.} +Таким образом, если пользователь перенаправил вывод ядра на последовательную +консоль, то по завершении загрузки он увидит на этой консоли приглашение для +логина\footnote{Отметим, что getty, а точнее, +agetty+ на такой консоли +вызывается с параметром +-s+, и поэтому не~изменяет настроек символьной +скорость (baud rate)~--- сохраняется то значение, которое было указано в строке +параметров ядра.}. Кроме того, systemd выполняет поиск консолей, предоставляемых +системами виртуализации, и запускает +serial-getty@.service+ на первой из этих +консолей (+/dev/hvc0+, +/dev/xvc0+ или +/dev/hvsi0+). Такое поведение +реализовано специальной +\href{http://www.freedesktop.org/wiki/Software/systemd/Generators}{программой-генератором}~--- +\href{http://www.freedesktop.org/software/systemd/man/systemd-getty-generator.html}{systemd-getty-generator}. +Генераторы запускаются в самом начале загрузки и автоматически настраивают +различные службы в зависимости от различных факторов. + +В большинстве случаев, вышеописанного механизма автоматической настройки должно +быть достаточно, чтобы получить приглашение логина там, где нужно~--- без +каких-либо дополнительных настроек systemd. Тем не~менее, иногда возникает +необходимость в ручной настройке~--- например, когда необходимо запустить getty +сразу на нескольких последовательных консолях, или когда вывод сообщений ядра +направляется на один терминал, а управление производится с другого. Для решения +таких задач достаточно определить по экземпляру +serial-getty@.service+ для +каждого последовательного порта, на котором вы хотите запустить +getty\footnote{Отметим, что +systemctl enable+ \emph{для экземпляров служб} +работает только начиная с systemd версии 188 и старше (например, в Fedora 18). В +более ранних версиях придется напрямую манипулировать символьными ссылками: +\texttt{ln -s /usr/lib/systemd/system/serial-getty@.service +/etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service ; systemctl +daemon-reload}.}: +\begin{Verbatim} +# systemctl enable serial-getty@ttyS2.service +# systemctl start serial-getty@ttyS2.service +\end{Verbatim} +После выполнения этих команд, getty будет принудительно запускаться для +указанных последовательных портов при всех последующих загрузках. + +В некоторых ситуациях может возникнуть необходимость в тонкой настройке +параметров getty (например, настроенная для ядра символьная скорость непригодна +для интерактивного сеанса). Тогда просто скопируйте штатный шаблон юнита в +каталог +/etc/systemd/system+ и отредактируйте полученную копию: +\begin{Verbatim} +# cp /usr/lib/systemd/system/serial-getty@.service /etc/systemd/system/serial-getty@ttyS2.service +# vi /etc/systemd/system/serial-getty@ttyS2.service + ... редактируем параметры запуска agetty ... +# ln -s /etc/systemd/system/serial-getty@ttyS2.service /etc/systemd/system/getty.target.wants/ +# systemctl daemon-reload +# systemctl start serial-getty@ttyS2.service +\end{Verbatim} +В приведенном примере создает файл настроек, определяющий запуск getty на порту ++ttyS2+ (это определяется именем, под которым мы скопировали файл~--- ++serial-getty@ttyS2.service+). Все изменения настроек, сделанные в этом файле, +будут распространяться только на этот порт. + +Собственно, это все, что я хотел рассказать о последовательных портах, +виртуальных консолях и запуске getty на них. Надеюсь, рассказ получился +интересным. + +\section{Работа с Journal} + +В свое время, я уже рассказывал о некоторых возможностях journal +(см.~главу~\ref{sec:journal}), доступных из утилиты +systemctl+. Сейчас я +попробую рассказать о journal более подробно, с упором на практическое +применение его возможностей. + +Если вы еще не~в курсе, что такое journal: это компонент +\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}, регистрирующий +сообщения из системного журнала (syslog), сообщения ядра (kernel log) и initrd, +а также сообщения, которые процессы служб выводят на STDOUT и STDERR. Полученная +информация индексируется и предоставляется пользователю по запросу. Journal +может работать одновременно с традиционными демоном syslog (например, rsyslog +или syslog-ng), либо полностью его заменять. Более подробно см. в +\href{http://0pointer.de/blog/projects/the-journal.html}{первом анонсе}. + +Journal был включен в Fedora начиная с F17. В Fedora~18 journal вырос в мощный и +удобный механизм работы с системным журналом. Однако, и в~F17, и в~F18 journal +по умолчанию сохраняет информацию только в небольшой кольцевой буфер в каталоге ++/run/log/journal+. Как и все содержимое каталога +/run+, эта информация +теряется при перезагрузке. Такой подход сильно ограничивает использование +полезных возможностей journal, однако вполне достаточен для вывода актуальных +сообщений от служб в +systemctl status+. Начиная с Fedora~19, мы собираемся +включить сохранение логов на диск, в каталог +/var/log/journal+. При этом, +логи смогут занимать гораздо больше места\footnote{Прим. перев.: В journal +отдельно задаются ограничения на размер для логов во временном хранилище +(+/run+) и в постоянном (+/var+). При превышении лимита старые журналы +удаляются. Так как +/run+ размещается на tmpfs, т.е. в +оперативной памяти, для временного хранения по умолчанию установлены более +жесткие ограничения. При необходимости, соответствующие настройки можно задать +в файле +\href{http://www.freedesktop.org/software/systemd/man/journald.conf.html}{journald.conf}.}, +а значит, смогут вместить больше полезной информации. Таким образом, journal +станет еще более удобным. + +\subsection{Сохранение логов на диск} + +В F17 и~F18 вы можете включить сохранение логов на диск вручную: +\begin{Verbatim} +# mkdir -p /var/log/journal +\end{Verbatim} +После этого рекомендуется перезагрузить систему, чтобы заполнить журнал овыми +записями. + +Так как теперь у вас есть journal, syslog вам больше не~нужен (кроме ситуаций, +когда вам совершенно необходимо иметь +/var/log/messages+ в текстовом виде), и +вы спокойно можете удалить его: +\begin{Verbatim} +# yum remove rsyslog +\end{Verbatim} + +\subsection{Основы} + +Итак, приступим. Нижеприведенный текст демонстрирует возможности systemd~195, +входящего в Fedora~18\footnote{Обновление со 195-й версией systemd в настоящее +время находится +\href{https://admin.fedoraproject.org/updates/FEDORA-2012-16709/systemd-195-1.fc18}{на +тестировании} и вскоре будет включено в состав Fedora~18.}, так что, если +некоторые из описанных трюков не~сработают в F17~--- пожалуйста, дождитесь F18. + +Начнем с основ. Доступ к логам journal осуществляется через утилиту +\href{http://www.freedesktop.org/software/systemd/man/journalctl.html}{journalctl(1)}. +Чтобы просто взглянуть на лог, достаточно ввести +\begin{Verbatim} +# journalctl +\end{Verbatim} +Если вы выполнили эту команду с полномочиями root, вы увидите все +журнальные сообщения, включая исходящие как от системных компонентов, так и от +залогиненных пользователей. Вывод этой команды форматируется в стиле ++/var/log/messages+, однако в нем добавлены кое-какие улучшения: +\begin{itemize} + \item Строки с приоритетом error и выше подсвечены красным. + \item Строки с приоритетом notice и warning выделены жирным шрифтом. + \item Все отметки времени сформированы с учетом вашего часового пояса. + \item Для навигации по тексту используется просмотрщик (pager), по + умолчанию +less+. + \item Выводятся \emph{все} доступные данные, включая информацию из + файлов, прошедших ротацию (rotated logs). + \item Загрузка системы отмечается специальной строкой, отделяющей + записи, сгенерированные между (пере)загрузками. +\end{itemize} + +Отметим, что в данной статье не~приводятся примеры такого вывода~--- прежде +всего, для краткости изложения, но также и для того, чтобы дать вам повод +поскорее попробовать Fedora~18 с systemd~195. Надеюсь, вы поймете суть и так. + +\subsection{Контроль доступа} + +Итак, мы получили удобный и эффективный метод просмотра логов. Но для полного +доступа к системным сообщениям требуются привилегии root, что не~всегда +удобно~--- в наше время администраторы предпочитают работать от имени +непривилегированного пользователя, переключаясь на root только при крайней +необходимости. По умолчанию, непривилегированные пользователи могут +просматривать в journal только свои собственные логи (сообщения, сгенерированные +их процессами). Чтобы предоставить пользователю доступ ко всем системным логам, +нужно включить его в группу +adm+: +\begin{Verbatim} +# usermod -a -G adm lennart +\end{Verbatim} +Разлогинившись, а затем вновь залогинившись под именем +lennart+\footnote{Прим. +перев.: Для того, чтобы обновить групповые полномочия в уже запущенных сеансах, +можно воспользоваться командой +\href{http://linux.die.net/man/1/newgrp}{newgrp(1)}: +newgrp adm+.}, я могу +просматривать сообщения от всех пользователей и системных +компонентов\footnote{Прим. перев.: Группа +adm+ была выбрана на основании опыта +дистрибутива Debian, в котором она устанавливается в качестве группы-владельца +большинства лог-файлов. При этом авторы четко разделяют полномочия групп +adm+ и ++wheel+: если последняя используется для предоставления прав \emph{изменять} +что-либо в системе, то первая дает возможность лишь \emph{просматривать} +системную информацию.}: +\begin{Verbatim} +$ journalctl +\end{Verbatim} + +\subsection{Отслеживание логов в реальном времени} + +Когда вы запускаете программу +journalctl+ без параметров, она выводит все +сообщения, сгенерированные на текущий момент. Однако, иногда бывает полезно +отслеживать их появление в режиме реального времени. В классической реализации +syslog это осуществлялось командой +tail -f /var/log/messages+. В journal ее +аналог выглядит так: +\begin{Verbatim} +$ journalctl -f +\end{Verbatim} +И работает он точно так же: выводит последние десять сообщений, после чего +переходит в режим ожидания, и выводит новые сообщения по мере их появления. + +\subsection{Простейшие методы выборки записей} + +При вызове +journalctl+ без параметров, она выводит все сообщения, начиная с +самого первого из сохраненных. Разумеется, это огромный объем информации. На +практике иногда бывает достаточно ограничиться сообщениями, сгенерированными с +момента последней загрузки системы: +\begin{Verbatim} +$ journalctl -b +\end{Verbatim} +Но часто даже после такой фильтрации записей остается довольно много. Что ж, мы +можем ограничиться только наиболее важными. Итак, все сообщения с приоритетом +error и выше, начиная с момента последней загрузки: +\begin{Verbatim} +$ journalctl -b -p err +\end{Verbatim} + +Если вы уже успели перезагрузить систему после того, как произошли интересующие +вас события, целесообразнее будет воспользоваться выборкой по времени: +\begin{Verbatim} +$ journalctl --since=yesterday +\end{Verbatim} +В результате мы увидим все сообщения, зарегистрированные начиная со вчерашнего +дня вплоть до настоящего момента. Прекрасно! Разумеется, этот критерий отбора можно +комбинировать с другими, например, с +-p err+. Но, допустим, нам нужно узнать о +чем-то, что случилось либо 15-го октября, либо 16-го: +\begin{Verbatim} +$ journalctl --since=2012-10-15 --until="2011-10-16 23:59:59" +\end{Verbatim} +Отлично, мы нашли то, что искали. Но вот вам сообщают, что сегодня ранним утром +наблюдались проблемы с CGI-скриптами Apache. Ладно, послушаем, что нам скажет +индеец: +\begin{Verbatim} +$ journalctl -u httpd --since=00:00 --until=9:30 +\end{Verbatim} +Да, мы нашли это. Хм, похоже, что причиной стала проблема с диском +/dev/sdc+. +Посмотрим, что с ним случилось: +\begin{Verbatim} +$ journalctl /dev/sdc +\end{Verbatim} +Кошмар, ошибка ввода-вывода!\footnote{Ну ладно, признаюсь, здесь я немножко +считерил. Индексирование сообщений ядра по блочным устройствам пока что +не~принято в апстрим, но Ганс +\href{http://www.spinics.net/lists/linux-scsi/msg62499.html}{проделал огромную +работу}, чтобы реализовать эту функциональность, и я надеюсь, что к релизу F18 +все будет.} Нужно срочно заменить диск, пока не~начались более серьезные +проблемы. Ладно, пошли дальше. Что у нас там случилось с процессом vpnc? +\begin{Verbatim} +$ journalctl /usr/sbin/vpnc +\end{Verbatim} +Хм, ничего подозрительного. Но, кажется, проблема где-то во взаимодействии между ++vpnc+ и +dhclient+. Посмотрим объединенный и отсортированный по времени списов +сообщений от этих процессов: +\begin{Verbatim} +$ journalctl /usr/sbin/vpnc /usr/sbin/dhclient +\end{Verbatim} +Отлично, мы нашли причину проблемы! + + + \end{document} vim:ft=tex:tw=80:spell:spelllang=ru