Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df098ff4c1 | ||
|
|
5ffca4f1be | ||
|
|
751d5d1bae |
746
s4a.tex
746
s4a.tex
@@ -20,6 +20,8 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
|
|||||||
\newcommand{\hreftt}[2]{\href{#1}{\texttt{#2}}}
|
\newcommand{\hreftt}[2]{\href{#1}{\texttt{#2}}}
|
||||||
\newenvironment{caveat}[1][]{\smallskip\par\textbf{Предупреждение#1: }}%
|
\newenvironment{caveat}[1][]{\smallskip\par\textbf{Предупреждение#1: }}%
|
||||||
{\smallskip\par}
|
{\smallskip\par}
|
||||||
|
\newcommand{\sfnote}[1]{\texorpdfstring{\protect\footnote%
|
||||||
|
{Прим. перев.: #1}}{}}
|
||||||
% Настройка макета страницы
|
% Настройка макета страницы
|
||||||
\setlength{\hoffset}{-1.5cm}
|
\setlength{\hoffset}{-1.5cm}
|
||||||
\addtolength{\textwidth}{2cm}
|
\addtolength{\textwidth}{2cm}
|
||||||
@@ -48,7 +50,8 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
|
|||||||
\href{http://creativecommons.org/licenses/by-sa/3.0/legalcode}{CC-BY-SA 3.0
|
\href{http://creativecommons.org/licenses/by-sa/3.0/legalcode}{CC-BY-SA 3.0
|
||||||
Unported}}
|
Unported}}
|
||||||
\maketitle
|
\maketitle
|
||||||
\tableofcontents%\newpage
|
\tableofcontents
|
||||||
|
\newpage
|
||||||
\sectiona{Предисловие автора}
|
\sectiona{Предисловие автора}
|
||||||
Многие из вас, наверное, уже знают, что
|
Многие из вас, наверное, уже знают, что
|
||||||
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}~--- это новая
|
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}~--- это новая
|
||||||
@@ -419,7 +422,12 @@ alias psc='ps xawf -eo pid,user,cgroup,args'
|
|||||||
|
|
||||||
Альтернативный способ получить ту же информацию~--- воспользоваться утилитой
|
Альтернативный способ получить ту же информацию~--- воспользоваться утилитой
|
||||||
+systemd-cgls+, входящей в комплект поставки systemd. Она отображает иерархию
|
+systemd-cgls+, входящей в комплект поставки systemd. Она отображает иерархию
|
||||||
контрольных групп в виде псевдографической диаграммы-дерева:
|
контрольных групп в виде псевдографической диаграммы-дерева\footnote{Прим.
|
||||||
|
перев.: Стоит заметить, что в нижеприведенном листинге используется
|
||||||
|
ASCII-псевдографика. Между тем, уже довольно давно отображение иерархии
|
||||||
|
процессов в +systemd-cgls+ и +systemctl status+ производится в более
|
||||||
|
выразительной ├юникодной └псевдографике. ASCII-вариант выводится только в том
|
||||||
|
случае, если консоль не~поддерживает Unicode.}:
|
||||||
|
|
||||||
\begin{landscape}
|
\begin{landscape}
|
||||||
\begin{Verbatim}[fontsize=\small]
|
\begin{Verbatim}[fontsize=\small]
|
||||||
@@ -966,6 +974,7 @@ Apache, crond, atd, которые по роду служебной деятел
|
|||||||
не~отдельному процессу.
|
не~отдельному процессу.
|
||||||
|
|
||||||
\section{Три уровня выключения}
|
\section{Три уровня выключения}
|
||||||
|
\label{sec:off}
|
||||||
|
|
||||||
В \href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} существует
|
В \href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} существует
|
||||||
три уровня (разновидности) действий, направленных на прекращение работы службы
|
три уровня (разновидности) действий, направленных на прекращение работы службы
|
||||||
@@ -2127,7 +2136,7 @@ systemd?
|
|||||||
позволяющей прочитать из файла набор переменных окружения, который будет
|
позволяющей прочитать из файла набор переменных окружения, который будет
|
||||||
установлен при запуске службы. Если же для задания настроек вам необходим
|
установлен при запуске службы. Если же для задания настроек вам необходим
|
||||||
полноценный язык программирования~--- ничто не~мешает им воспользоваться.
|
полноценный язык программирования~--- ничто не~мешает им воспользоваться.
|
||||||
Например, вы можете создайть в +/usr/lib/<your package>/+ простой скрипт,
|
Например, вы можете создать в +/usr/lib/<your package>/+ простой скрипт,
|
||||||
который включает соответствующие файлы, а затем запускает бинарник демона через
|
который включает соответствующие файлы, а затем запускает бинарник демона через
|
||||||
+exec+. После чего достаточно просто указать этот скрипт в опции +ExecStart=+
|
+exec+. После чего достаточно просто указать этот скрипт в опции +ExecStart=+
|
||||||
вместо бинарника демона.
|
вместо бинарника демона.
|
||||||
@@ -3132,7 +3141,7 @@ URI, ссылающиеся на документацию, формируютс
|
|||||||
Да, кстати: если вас интересует общий обзор процесса загрузки systemd, то вам
|
Да, кстати: если вас интересует общий обзор процесса загрузки systemd, то вам
|
||||||
стоит обратить внимание на
|
стоит обратить внимание на
|
||||||
\href{http://www.freedesktop.org/software/systemd/man/bootup.html}{новую
|
\href{http://www.freedesktop.org/software/systemd/man/bootup.html}{новую
|
||||||
страницу руководства}, где представлена псевгдорафическая потоковая диаграмма,
|
страницу руководства}, где представлена псевдографическая потоковая диаграмма,
|
||||||
описывающая процесс загрузки и роль ключевых юнитов.
|
описывающая процесс загрузки и роль ключевых юнитов.
|
||||||
|
|
||||||
\section{Сторожевые таймеры}
|
\section{Сторожевые таймеры}
|
||||||
@@ -3456,7 +3465,7 @@ getty. Таким образом, вам достаточно лишь прав
|
|||||||
консоль, то по завершении загрузки он увидит на этой консоли приглашение для
|
консоль, то по завершении загрузки он увидит на этой консоли приглашение для
|
||||||
логина\footnote{Отметим, что getty, а точнее, +agetty+ на такой консоли
|
логина\footnote{Отметим, что getty, а точнее, +agetty+ на такой консоли
|
||||||
вызывается с параметром +-s+, и поэтому не~изменяет настроек символьной
|
вызывается с параметром +-s+, и поэтому не~изменяет настроек символьной
|
||||||
скорость (baud rate)~--- сохраняется то значение, которое было указано в строке
|
скорости (baud rate)~--- сохраняется то значение, которое было указано в строке
|
||||||
параметров ядра.}. Кроме того, systemd выполняет поиск консолей, предоставляемых
|
параметров ядра.}. Кроме того, systemd выполняет поиск консолей, предоставляемых
|
||||||
системами виртуализации, и запускает +serial-getty@.service+ на первой из этих
|
системами виртуализации, и запускает +serial-getty@.service+ на первой из этих
|
||||||
консолей (+/dev/hvc0+, +/dev/xvc0+ или +/dev/hvsi0+). Такое поведение
|
консолей (+/dev/hvc0+, +/dev/xvc0+ или +/dev/hvsi0+). Такое поведение
|
||||||
@@ -3479,7 +3488,15 @@ getty\footnote{Отметим, что +systemctl enable+ \emph{для экзем
|
|||||||
более ранних версиях придется напрямую манипулировать символьными ссылками:
|
более ранних версиях придется напрямую манипулировать символьными ссылками:
|
||||||
\texttt{ln -s /usr/lib/systemd/system/serial-getty@.service
|
\texttt{ln -s /usr/lib/systemd/system/serial-getty@.service
|
||||||
/etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service ; systemctl
|
/etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service ; systemctl
|
||||||
daemon-reload}.}:
|
daemon-reload}.}\footnote{Прим. перев.: На самом деле, работать с символьными
|
||||||
|
ссылками придется даже в современных версиях systemd (на момент написания этих
|
||||||
|
строк, последней является версия 202), так как разработчики забыли включить в
|
||||||
|
файл +serial-getty@.service+ секцию +[Install]+, в результате чего попытка
|
||||||
|
выполнения +systemctl enable+ для экземпляра соответствующей службы ведет к
|
||||||
|
закономерной ошибке. Впрочем, исправить это несложно: достаточно скопировать
|
||||||
|
данный файл в +/etc/systemd/system/+, после чего дописать в него секцию
|
||||||
|
+[Install]+ с параметром +WantedBy=getty.target+, а затем выполнить
|
||||||
|
+systemctl daemon-reload+.}:
|
||||||
\begin{Verbatim}
|
\begin{Verbatim}
|
||||||
# systemctl enable serial-getty@ttyS2.service
|
# systemctl enable serial-getty@ttyS2.service
|
||||||
# systemctl start serial-getty@ttyS2.service
|
# systemctl start serial-getty@ttyS2.service
|
||||||
@@ -3628,7 +3645,10 @@ Journal был включен в Fedora начиная с F17. В Fedora~18 jour
|
|||||||
большинства лог-файлов. При этом авторы четко разделяют полномочия групп +adm+ и
|
большинства лог-файлов. При этом авторы четко разделяют полномочия групп +adm+ и
|
||||||
+wheel+: если последняя используется для предоставления прав \emph{изменять}
|
+wheel+: если последняя используется для предоставления прав \emph{изменять}
|
||||||
что-либо в системе, то первая дает возможность лишь \emph{просматривать}
|
что-либо в системе, то первая дает возможность лишь \emph{просматривать}
|
||||||
системную информацию.}:
|
системную информацию. Начиная с версии systemd 198, группа-владелец файлов
|
||||||
|
журнала изменена с +adm+ на +systemd-journal+, однако штатный алгоритм установки
|
||||||
|
systemd все равно выдает права на их чтение группам +adm+ и +wheel+ (через
|
||||||
|
ACL).}:
|
||||||
\begin{Verbatim}
|
\begin{Verbatim}
|
||||||
$ journalctl
|
$ journalctl
|
||||||
\end{Verbatim}
|
\end{Verbatim}
|
||||||
@@ -3804,7 +3824,7 @@ $ journalctl -F _SYSTEMD_UNIT
|
|||||||
однако, начиная с релиза systemd 196, аналогичная функциональность доступна и
|
однако, начиная с релиза systemd 196, аналогичная функциональность доступна и
|
||||||
для zsh.}! Это же просто прекрасно~--- вы можете просмотреть перечень значений
|
для zsh.}! Это же просто прекрасно~--- вы можете просмотреть перечень значений
|
||||||
поля и выбрать из него нужно прямо при вводе выражения. Возьмем для примера
|
поля и выбрать из него нужно прямо при вводе выражения. Возьмем для примера
|
||||||
метки SELinux. Помнится, имя поле начиналось с букв SE\ldots{}
|
метки SELinux. Помнится, имя поля начиналось с букв SE\ldots{}
|
||||||
\begin{Verbatim}[commandchars=\\\{\}]
|
\begin{Verbatim}[commandchars=\\\{\}]
|
||||||
$ journalctl _SE\textbf{<TAB>}
|
$ journalctl _SE\textbf{<TAB>}
|
||||||
\end{Verbatim}
|
\end{Verbatim}
|
||||||
@@ -3956,18 +3976,32 @@ CPUShares=1500
|
|||||||
\end{Verbatim}
|
\end{Verbatim}
|
||||||
Первая строка обеспечивает включение в нашу конфигурацию файла с настройками по
|
Первая строка обеспечивает включение в нашу конфигурацию файла с настройками по
|
||||||
умолчанию, сделанными разработчиками Apache или его сопровождающими в вашем
|
умолчанию, сделанными разработчиками Apache или его сопровождающими в вашем
|
||||||
дистрибутиве (если это включение не~указать явно, данный файл будет проигнорирован).
|
дистрибутиве (если это включение не~указать явно, данный файл будет
|
||||||
Далее, мы указываем тот параметр, который хотим изменить. Сохраняем файл,
|
проигнорирован). Далее, мы указываем тот параметр, который хотим
|
||||||
приказываем systemd перечитать конфигурацию, и перезапускаем Apache, чтобы
|
изменить\footnote{Прим. перев.: В новых версиях systemd, начиная со 198, можно
|
||||||
настройки вступили в силу\footnote{Прим. перев.: systemd версий до 197
|
поступить проще: вместо того, чтобы создавать свой юнит-файл в каталоге +/etc+ и
|
||||||
включительно, не~поддерживает изменение параметров контрольных групп без
|
включать в него содержимое штатного (из +/usr+), достаточно просто создать
|
||||||
перезапуска службы. Но вы можете узнать контрольную группу службы командой
|
каталог +/etc/systemd/system/httpd.service.d/+ и поместить в него файл
|
||||||
наподобие +systemctl show -p ControlGroup avahi-daemon.service+, и выполнить
|
+my_resource_limit.conf+ (суффикс +.conf+ обязателен), в котором указываются
|
||||||
настройки любым удобным для вас способом, например, через запись значений в
|
только те настройки, которые необходимо изменить (последние две строки
|
||||||
псевдофайлы cgroupfs (разумеется, при следующем запуске службы к ней будут
|
вышеприведенного листинга). Это никак не~отменяет основного конфигурационного
|
||||||
применены параметры, указанные в конфигурационном файле). Начиная с systemd 198,
|
файла юнита (который может находиться в +/usr+ или +/etc+), однако настройки из
|
||||||
в программу +systemctl+ добавлена поддержка команд +set-cgroup-attr+,
|
+.d+-каталогов имеют более высокий приоритет и могут перекрывать настройки
|
||||||
+unset-cgroup-attr+ и +get-cgroup-attr+.}:
|
основного файла. Все вышесказанное относится и к другим примерам из этого
|
||||||
|
раздела.}. Сохраняем файл, приказываем systemd перечитать конфигурацию, и
|
||||||
|
перезапускаем Apache, чтобы настройки вступили в силу\footnote{Прим. перев.:
|
||||||
|
systemd версий до 197 включительно, не~поддерживает изменение параметров
|
||||||
|
контрольных групп без перезапуска службы. Но вы можете узнать контрольную группу
|
||||||
|
службы командой наподобие +systemctl show -p ControlGroup avahi-daemon.service+,
|
||||||
|
и выполнить настройки любым удобным для вас способом, например, через запись
|
||||||
|
значений в псевдофайлы cgroupfs (разумеется, при следующем запуске службы к ней
|
||||||
|
будут применены параметры, указанные в конфигурационном файле). Начиная с
|
||||||
|
systemd 198, в программу +systemctl+ добавлена поддержка команд
|
||||||
|
+set-cgroup-attr+, +unset-cgroup-attr+ и +get-cgroup-attr+, позволяющих
|
||||||
|
манипулировать практически всеми параметрами контрольных групп. При этом
|
||||||
|
поддерживается сохранение установленных таким образом параметров в виде
|
||||||
|
вспомогательных конфигурационных файлов в +.d+-каталогах (см. примечание
|
||||||
|
выше).}:
|
||||||
\begin{Verbatim}
|
\begin{Verbatim}
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl restart httpd.service
|
systemctl restart httpd.service
|
||||||
@@ -4242,7 +4276,7 @@ fi
|
|||||||
\end{Verbatim}
|
\end{Verbatim}
|
||||||
|
|
||||||
Эта утилита возвращает код 0 (успех), обнаружив виртуализацию, или ненулевое
|
Эта утилита возвращает код 0 (успех), обнаружив виртуализацию, или ненулевое
|
||||||
значение, если виртуализация не~выявлена. Кроме того, она выводит идентификатор
|
значение, если виртуализация не~выявлена. Также она выводит идентификатор
|
||||||
обнаруженной системы виртуализации (согласно списку выше), если это не~было
|
обнаруженной системы виртуализации (согласно списку выше), если это не~было
|
||||||
запрещено опцией +-q+. Кроме того, опции +-c+ и +-v+ позволяют ограничить
|
запрещено опцией +-q+. Кроме того, опции +-c+ и +-v+ позволяют ограничить
|
||||||
проверки только механизмами виртуализации на уровне ОС, либо полной
|
проверки только механизмами виртуализации на уровне ОС, либо полной
|
||||||
@@ -4343,8 +4377,8 @@ systemd в промышленных серверных платформах, м
|
|||||||
Подобные конфигурации уже используются на рабочих серверах ряда компаний. В
|
Подобные конфигурации уже используются на рабочих серверах ряда компаний. В
|
||||||
частности, специалисты из \href{https://www.getpantheon.com/}{Pantheon}
|
частности, специалисты из \href{https://www.getpantheon.com/}{Pantheon}
|
||||||
используют такую схему для обслуживания масштабируемой инфраструктуры множества
|
используют такую схему для обслуживания масштабируемой инфраструктуры множества
|
||||||
сайтов на базе Drupal. (Стоит упомянуть, что заслуга ее внедрения в Pantheon
|
сайтов на базе Drupal. (Стоит упомянуть, что заслуга ее внедрения в компании
|
||||||
принадлежит Дэвиду Штрауссу. Дэвид, ты крут!)
|
Pantheon принадлежит Дэвиду Штрауссу. Дэвид, ты крут!)
|
||||||
|
|
||||||
\subsection{Сокет-активация контейнеров}
|
\subsection{Сокет-активация контейнеров}
|
||||||
|
|
||||||
@@ -4527,13 +4561,10 @@ systemd начнет прослушивать TCP-порт 23. При подкл
|
|||||||
классические inetd-службы, кроме встроенных) или systemd (зависят от библиотеки
|
классические inetd-службы, кроме встроенных) или systemd (зависят от библиотеки
|
||||||
+libsystemd-daemon.so+, либо содержат в исходниках заголовочный файл
|
+libsystemd-daemon.so+, либо содержат в исходниках заголовочный файл
|
||||||
+sd-daemon.h+). Службы, которые сами открывают себе слушающий сокет и
|
+sd-daemon.h+). Службы, которые сами открывают себе слушающий сокет и
|
||||||
не~содержат кода для приема уже открытого сокета, так активировать нельзя.
|
не~содержат кода для приема уже открытого сокета, так активировать нельзя.}, а
|
||||||
Точнее, в случае с сетевыми и файловыми сокетами, все-таки можно, но первое
|
те сокеты, которые будут настроены для прослушивания внутри контейнера, но
|
||||||
соединение/сообщение при этом будет <<потрачено>> на запуск контейнера, и до
|
не~получены от хоста, будут активированы и доступны изнутри контейнера (а если
|
||||||
службы в итоге дойдут только последующие, начина со второго, что сводит выгоды
|
это сетевые или файловые unix-сокеты, то и извне).
|
||||||
практически к нулю.}, а те сокеты, которые будут настроены для прослушивания
|
|
||||||
внутри контейнера, но не~получены от хоста, будут активированы и доступны
|
|
||||||
изнутри контейнера (а если это сетевые или файловые unix-сокеты, то и извне).
|
|
||||||
|
|
||||||
Итак, давайте отступим чуть назад и полюбуемся на результаты наших трудов. Что
|
Итак, давайте отступим чуть назад и полюбуемся на результаты наших трудов. Что
|
||||||
мы получили в итоге? Возможность настраивать на одном хосте множество
|
мы получили в итоге? Возможность настраивать на одном хосте множество
|
||||||
@@ -4579,6 +4610,661 @@ systemd, начиная с версии 197. Тем не~менее, наша р
|
|||||||
мощных и хорошо масштабируемых серверных систем. За дополнительной информацией
|
мощных и хорошо масштабируемых серверных систем. За дополнительной информацией
|
||||||
обращайтесь к документации или приходите на наш IRC-канал. Спасибо за внимание!
|
обращайтесь к документации или приходите на наш IRC-канал. Спасибо за внимание!
|
||||||
|
|
||||||
|
\appendix
|
||||||
|
|
||||||
|
\section{Диагностика неполадок\sfnote{Перевод статьи
|
||||||
|
<<\href{http://freedesktop.org/wiki/Software/systemd/Debugging}{Debugging
|
||||||
|
systemd Problems}>> с официального сайта проекта, по состоянию на 2013-01-08
|
||||||
|
19:13:31 (ревизия \No26).}}
|
||||||
|
|
||||||
|
\subsection{Диагностика проблем с загрузкой}
|
||||||
|
|
||||||
|
Если система зависает во время загрузки, прежде всего нужно разобраться, на
|
||||||
|
каком этапе возникает проблема~--- до запуска systemd, или после.
|
||||||
|
|
||||||
|
Для этого надо удалить из командной стоки ядра параметры +quiet+ и +rhgb+. При
|
||||||
|
работе systemd на экран выводятся примерно такие сообщения:
|
||||||
|
\begin{Verbatim}[commandchars=\\\{\}]
|
||||||
|
Welcome to \textcolor{blue}{Fedora \emph{ВЕРСИЯ} (\emph{имя релиза})}!
|
||||||
|
Starting \emph{название}...
|
||||||
|
[ \textcolor{green}{OK} ] Stared \emph{название}...
|
||||||
|
\end{Verbatim}
|
||||||
|
(Пример можно посмотреть на
|
||||||
|
\href{http://freedesktop.org/wiki/Software/systemd/Debugging?action=AttachFile&do=view&target=f17boot.png}{скриншоте}.)
|
||||||
|
|
||||||
|
Если у вас есть доступ к оболочке, это значительно упрощает диагностику и
|
||||||
|
решение проблем. В том случае, когда до приглашения входа в систему дело так и
|
||||||
|
не~доходит, попробуйте переключиться на другую виртуальную консоль, нажав
|
||||||
|
CTRL--ALT--F<\emph{цифра}>. Дело в том, что при проблемах, связанных с запуском
|
||||||
|
X-сервера, может возникать ситуация, когда на первой консоли (+tty1+)
|
||||||
|
приглашение ко входу отсутствует, но все остальные консоли при этом работают
|
||||||
|
нормально.
|
||||||
|
|
||||||
|
Если ни~на одной из виртуальных консолей приглашение так и не~появилось~---
|
||||||
|
попробуйте выждать еще \emph{порядка 5 минут}. Только после этого можно
|
||||||
|
будет считать процесс загрузки окончательно зависшим. Если подвисание
|
||||||
|
обусловлено всего лишь сбоем при запуске какой-то службы, то после истечения
|
||||||
|
тайм-аута проблемная служба будет убита, и загрузка продолжится. Другой
|
||||||
|
вариант~--- отсутствует устройство, которое должно быть смонтировано для
|
||||||
|
нормальной работы системы. В этом случае загрузка будет остановлена, и система
|
||||||
|
перейдет в \emph{аварийный режим (emergency mode)}.
|
||||||
|
|
||||||
|
\subsubsection{Если у вас нет~доступа к оболочке}
|
||||||
|
|
||||||
|
Если система не~предоставила вам ни~нормального приглашения, ни~аварийной
|
||||||
|
оболочки, то для диагностики проблемы нужно выполнить следующие действия:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Попытайтесь перезагрузить систему, нажав CTRL--ALT--DEL. Если после
|
||||||
|
этого перезагрузки не~произойдет~--- обязательно укажите данное
|
||||||
|
обстоятельство, когда будете писать отчет об ошибке (bugreport).
|
||||||
|
Чтобы перезагрузить систему, вы можете воспользоваться
|
||||||
|
\href{http://fedoraproject.org/wiki/QA/Sysrq}{SysRq} или
|
||||||
|
<<аппаратным>> методом.
|
||||||
|
\item При следующей загрузке попробуйте воспользоваться некоторыми
|
||||||
|
нижеописанными стратегиями.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[Вывод диагностических сообщений на последовательную консоль]%
|
||||||
|
\hypertarget{it:serial}{} Если у вас под рукой есть терминал
|
||||||
|
последовательной консоли, либо дело происходит в виртуальной машине (в
|
||||||
|
частности, virt-manager позволяет просматривать вывод виртуальной машины
|
||||||
|
на последовательную консоль: меню Вид (View)~$\Rightarrow$ Текстовые
|
||||||
|
консоли (Text Consoles)), вы можете попросить systemd выводить на эту
|
||||||
|
консоль подробную отладочную информацию о ходе загрузки, добавив к
|
||||||
|
параметрам ядра следующие аргументы:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemd.log_level=debug systemd.log_target=console console=ttyS0,38400
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
\item[Загрузка в восстановительном (rescue) или аварийном (emergency)
|
||||||
|
режимах] Чтобы загрузиться в восстановительном режиме, добавьте к
|
||||||
|
параметрам ядра +systemd.unit=rescue.target+, или просто +1+. Это режим
|
||||||
|
эффективен для решения проблем, возникающих на этапе запуска обычных
|
||||||
|
служб, когда ключевые компоненты системы уже инициализированы. В такой
|
||||||
|
ситуации, вы можете просто отключить проблемную службу. Если же загрузка
|
||||||
|
не~доходит даже до восстановительного режима~--- попробуйте менее
|
||||||
|
требовательный, аварийный режим.
|
||||||
|
|
||||||
|
Для загрузки напрямую в режим аварийной оболочки, добавьте к параметрам
|
||||||
|
ядра +systemd.unit=emergency.target+, или просто +emergency+. Обратите
|
||||||
|
внимание, что в аварийном режиме корневая система по умолчанию
|
||||||
|
монтируется в режиме <<только для чтения>>, поэтому перед
|
||||||
|
восстановительными работами, связанными с записью на диск, необходимо
|
||||||
|
перемонтировать ее в режиме <<для чтения и записи>>:
|
||||||
|
\begin{Verbatim}
|
||||||
|
mount -o remount,rw /
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Как правило, аварийная оболочка используется для исправления
|
||||||
|
некорректных записей в +/etc/fstab+. После внесения необходимых
|
||||||
|
изменений, скомандуйте +systemctl daemon-reload+, чтобы systemd увидел
|
||||||
|
ваши исправления.
|
||||||
|
|
||||||
|
Если не~работает даже аварийный режим, попробуйте загрузиться напрямую в
|
||||||
|
оболочку, добавив к параметрам ядра +init=/bin/sh+. Такая ситуация может
|
||||||
|
возникнуть вследствие повреждения бинарного файла systemd, либо
|
||||||
|
библиотек, которые он использует. В этом случае может помочь
|
||||||
|
переустановка соответствующих пакетов.
|
||||||
|
|
||||||
|
Если не~срабатывает даже +init=/bin/sh+, остается лишь попробовать
|
||||||
|
загрузиться с другого носителя.
|
||||||
|
|
||||||
|
\item[Отладочная оболочка]\hypertarget{it:dbgshell}{}
|
||||||
|
Вы можете включить специальную отладочную оболочку, которая запускается
|
||||||
|
в отдельной консоли на раннем этапе загрузки и позволяет собрать
|
||||||
|
необходимую диагностическую информацию, а также провести
|
||||||
|
восстановительные операции. Для включения отладочной оболочки
|
||||||
|
скомандуйте
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl enable debug-shell.service
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
\textbf{Совет:} Если вы используете старую версию systemd, в которой еще
|
||||||
|
не~реализована поддержка отладочной оболочки, вы можете загрузить
|
||||||
|
соответствующий файл конфигурации юнита из
|
||||||
|
\href{http://cgit.freedesktop.org/systemd/systemd/plain/units/debug-shell.service.in}{git-репозитария
|
||||||
|
systemd}. Перед использованием этого файла, замените в нем +@sushell@+
|
||||||
|
на +/bin/bash+.
|
||||||
|
|
||||||
|
\textbf{Совет:} Если вы не~можете воспользоваться командой +systemctl+
|
||||||
|
(например, загрузились с помощью другой операционной системы), вы можете
|
||||||
|
выполнить соответствующие действия и напрямую:
|
||||||
|
\begin{Verbatim}
|
||||||
|
cd $ПУТЬ_К_ВАШЕМУ_КОРНЮ/etc/systemd/system
|
||||||
|
mkdir -p sysinit.target.wants
|
||||||
|
ln -s /lib/systemd/system/debug-shell.service sysinit.target.wants/
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Отладочная оболочка будет запущена с правами +root+ на консоли +tty9+
|
||||||
|
при следующей загрузке системы. Чтобы переключиться на нее, нажмите
|
||||||
|
CTRL--ALT--F9. Оболочка запускается на самом раннем этапе загрузки и
|
||||||
|
позволяет вам проверять состояние служб, читать системные журналы,
|
||||||
|
выявлять зависшие задачи (командой +systemctl list-jobs+) и т.д.
|
||||||
|
|
||||||
|
\textbf{Предупреждение:} Используйте эту оболочку только для отладки!
|
||||||
|
Не~забудьте отключить ее после того, как разберетесь с проблемами.
|
||||||
|
Оставлять доступную всем и каждому оболочку с правами +root+, мягко
|
||||||
|
говоря, небезопасно.
|
||||||
|
|
||||||
|
\item[Проверка параметров ядра] Для корректной загрузки системы необходимо,
|
||||||
|
чтобы каталог +/dev+ был заполнен, хотя бы частично. Убедитесь, что ядро
|
||||||
|
Linux собрано с опциями +CONFIG_DEVTMPFS+ и +CONFIG_DEVTMPFS_MOUNT+.
|
||||||
|
Кроме того, для корректной работы systemd рекомендуется включить
|
||||||
|
поддержку контрольных групп и fanotify (опции +CONFIG_CGROUPS+ и
|
||||||
|
+CONFIG_FANOTIFY+ соответственно). Отключение этих опций может привести
|
||||||
|
к появлению сообщений об ошибках вида <<Failed to get D-Bus
|
||||||
|
connection: No connection to service manager.>> при попытке запуска
|
||||||
|
+systemctl+.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
\subsubsection{Если у вас есть доступ к оболочке}
|
||||||
|
|
||||||
|
Если вам все-таки удалось получить доступ к оболочке системы, вы можете
|
||||||
|
воспользоваться ею для сбора диагностической информации. Загрузите систему со
|
||||||
|
следующими параметрами ядра:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M
|
||||||
|
\end{Verbatim}
|
||||||
|
В соответствии с ними, systemd будет выводить максимально подробные сообщения о
|
||||||
|
процессе загрузки, и направлять их в кольцевой буфер ядра (последний параметр
|
||||||
|
обеспечивает соответствующее увеличение размера буфера). Дождавшись запуска
|
||||||
|
оболочки, сохраните полученный журнал:
|
||||||
|
\begin{Verbatim}
|
||||||
|
dmesg > dmesg.txt
|
||||||
|
\end{Verbatim}
|
||||||
|
Отправляя отчет об ошибке, присоедините к нему полученный файл +dmesg.txt+.
|
||||||
|
|
||||||
|
Также, вы можете просмотреть список операций, чтобы выявить зависшие задачи:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl list-jobs
|
||||||
|
\end{Verbatim}
|
||||||
|
Операции, находящиеся в состоянии <<waiting>>, будут запущены на исполнение
|
||||||
|
только после того, как завершатся операции, выполняемые в данный момент
|
||||||
|
(состояние <<running>>).
|
||||||
|
|
||||||
|
\subsection{Диагностика проблем с выключением системы}
|
||||||
|
|
||||||
|
При зависании системы во время выключения, как и в случае с загрузкой,
|
||||||
|
рекомендуется подождать \emph{минимум 5 минут}, чтобы отличить полное зависание
|
||||||
|
системы от временного подвисания из-за проблем с отдельными службами. Также
|
||||||
|
стоит проверить, реагирует ли система на нажатие CTRL--ALT--DEL.
|
||||||
|
|
||||||
|
Если процесс остановки системы (при выключении или перезагрузке) зависает
|
||||||
|
полностью, прежде всего нужно убедиться, способно ли ядро Linux выключить или
|
||||||
|
перезагрузить систему. Для этого воспользуйтесь одной из команд:
|
||||||
|
\begin{Verbatim}
|
||||||
|
sync && reboot -f
|
||||||
|
sync && poweroff -f
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Если хотя бы одна из этих команд не~сработает~--- значит, проблема не~в systemd,
|
||||||
|
а в ядре.
|
||||||
|
|
||||||
|
\subsubsection{Система очень долго выключается}
|
||||||
|
|
||||||
|
Если ваша система все же может выключиться/перезагрузиться, но этот процесс
|
||||||
|
длится подозрительно долго, выполните нижеописанные операции:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Загрузите систему со следующими параметрами ядра:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M enforcing=0
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
\item Создайте файл +/lib/systemd/system-shutdown/debug.sh+, добавьте
|
||||||
|
ему право на запуск и запишите в него следующие строки:
|
||||||
|
\begin{Verbatim}
|
||||||
|
#!/bin/sh
|
||||||
|
mount -o remount,rw /
|
||||||
|
dmesg > /shutdown-log.txt
|
||||||
|
mount -o remount,ro /
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
\item Перезагрузите систему.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
После этого вы можете самостоятельно проанализировать файл +/shutdown-log.txt+,
|
||||||
|
и/или присоединить его к вашему сообщению об ошибке.
|
||||||
|
|
||||||
|
\subsubsection{Система не~может выключиться самостоятельно}
|
||||||
|
|
||||||
|
Если процесс выключения или перезагрузки вашей системы не~завершается даже через
|
||||||
|
несколько минут, и вышеописанный метод с +shutdown-log+ не~сработал, вы можете
|
||||||
|
собрать диагностическую информацию другими методами (которые мы уже
|
||||||
|
рассматривали применительно к проблемам загрузки):
|
||||||
|
\begin{itemize}
|
||||||
|
\item Используйте \hyperlink{it:serial}{последовательную консоль}.
|
||||||
|
\item Воспользуйтесь \hyperlink{it:dbgshell}{отладочной оболочкой}~---
|
||||||
|
она полезна не~только на ранних стадиях загрузки, но и на
|
||||||
|
поздних стадиях остановки системы.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\subsection{Просмотр состояния службы и ее журнала}
|
||||||
|
|
||||||
|
Когда при запуске службы происходит сбой, systemd выводит весьма абстрактное
|
||||||
|
сообщение об ошибке:
|
||||||
|
\begin{Verbatim}
|
||||||
|
# systemctl start foo.service
|
||||||
|
Job failed. See system journal and 'systemctl status' for details.
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
При этом сама служба может выводить собственное сообщение, но вы (пока что) его
|
||||||
|
не~видите. Дело в том, что запуск служб происходит не~из вашей оболочки, а из
|
||||||
|
процесса systemd, и поэтому вывод программы не~привязан к вашей консоли. Тем
|
||||||
|
не~менее, это вовсе не~означает, что выводимые сообщения теряются. По умолчанию,
|
||||||
|
потоки STDOUT и STDERR, принадлежащие запускаемым службам, перенаправляются в
|
||||||
|
системный журнал (journal). Туда же попадают и сообщения, отправляемые с помощью
|
||||||
|
функции +syslog(3)+. Кроме того, systemd записывает код выхода сбойных
|
||||||
|
процессов. Посмотреть собранные данные можно, например, так:
|
||||||
|
\begin{Verbatim}
|
||||||
|
# systemctl status foo.service
|
||||||
|
foo.service - mmm service
|
||||||
|
Loaded: loaded (/etc/systemd/system/foo.service; static)
|
||||||
|
Active: failed (Result: exit-code) since Fri, 11 May 2012 20:26:23 +0200; 4s ago
|
||||||
|
Process: 1329 ExecStart=/usr/local/bin/foo (code=exited, status=1/FAILURE)
|
||||||
|
CGroup: name=systemd:/system/foo.service
|
||||||
|
|
||||||
|
May 11 20:26:23 scratch foo[1329]: Failed to parse config
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
В нашем примере, служба запустилась как процесс с идентификатором (PID) 1329,
|
||||||
|
после чего завершилась с кодом выхода 1. Если вы запустили команду
|
||||||
|
+systemctl status+ от имени пользователя +root+, либо от имени пользователя,
|
||||||
|
входящего в группу +adm+, вы также увидите последние несколько строчек,
|
||||||
|
записанные службой в журнал. В нашем примере служба выдала всего одно сообщение
|
||||||
|
(<<Failed to parse config>>).
|
||||||
|
|
||||||
|
Чтобы просмотреть весь журнал целиком, воспользуйтесь командой +journalctl+.
|
||||||
|
|
||||||
|
Если одновременно с journal вы используете и классический демон системного лога
|
||||||
|
(например, rsyslog), то все сообщения из журнала будут переданы также и этому
|
||||||
|
демону, который запишет их в традиционные лог-файлы (в какие именно~--- зависит
|
||||||
|
от его настроек, обычно +/var/log/messages+).
|
||||||
|
|
||||||
|
\subsection{Подготовка сообщений об ошибках}
|
||||||
|
|
||||||
|
Если вы собираетесь отправить сообщение об ошибке в systemd, пожалуйста,
|
||||||
|
включите в него диагностическую информацию, в частности, содержимое системных
|
||||||
|
журналов. Журналы должны быть полными (без вырезок), не~заархивированными, с
|
||||||
|
MIME-типом +text/plain+.
|
||||||
|
|
||||||
|
Прежде всего, отправьте сообщение в багтрекер своего дистрибутива. Если же вы
|
||||||
|
твердо уверены, что проблема именно в апстримном systemd, проверьте сначала
|
||||||
|
список
|
||||||
|
\href{https://bugs.freedesktop.org/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=systemd}{уже
|
||||||
|
известных ошибок}. Если вы не~найдете в нем своего случая~---
|
||||||
|
\href{https://bugs.freedesktop.org/enter_bug.cgi?product=systemd}{заводите новую
|
||||||
|
запись}.
|
||||||
|
|
||||||
|
\subsubsection{Что нужно включить в сообщение об ошибке}
|
||||||
|
|
||||||
|
По возможности, пожалуйста, укажите в самом сообщении, либо присоедините к нему,
|
||||||
|
следующую информацию:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Строку параметров ядра, если она отличается от значения по
|
||||||
|
умолчанию. Ее можно найти в файле конфигурации загрузчика
|
||||||
|
(например, +/boot/grub2/grub.cfg+) или в специальном файле
|
||||||
|
+/proc/cmdline+.
|
||||||
|
\item Копию файла +/var/log/messages+.
|
||||||
|
\item Файл +dmesg.txt+, полученный после выполнения команды
|
||||||
|
\begin{Verbatim}
|
||||||
|
dmesg > dmesg.txt
|
||||||
|
\end{Verbatim}
|
||||||
|
Перед ее выполнением лучше загрузиться с параметрами ядра
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M
|
||||||
|
\end{Verbatim}
|
||||||
|
\item Файл +systemd-dump.txt+, полученный в результате выполнения
|
||||||
|
команды
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl dump > systemd-dump.txt
|
||||||
|
\end{Verbatim}
|
||||||
|
\item Файл +systemd-test.txt+, полученный при помощи команды
|
||||||
|
\begin{Verbatim}
|
||||||
|
/usr/bin/systemd --test --system --log-level=debug > systemd-test.txt 2>&1
|
||||||
|
\end{Verbatim}
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\section{Специальные файловые системы\sfnote{Перевод статьи
|
||||||
|
<<\href{http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems}{API
|
||||||
|
File Systems}>> с официального сайта проекта, по состоянию на 2013-01-17
|
||||||
|
11:06:59 (ревизия \No14).}}
|
||||||
|
|
||||||
|
\emph{Итак, вы запустили программу mount(8), и увидели в ее выводе множество
|
||||||
|
странных файловых систем, не~указанных в /etc/fstab. У вас могут возникнуть
|
||||||
|
вопросы: <<Как их убрать?>> или <<Как задать для них параметры монтирования?>>.}
|
||||||
|
|
||||||
|
В Linux предусмотрено несколько способов взаимодействия программ из пространства
|
||||||
|
пользователя с ядром. Наиболее популярными механизмами являются системные вызовы
|
||||||
|
(syscall), интерфейсы Netlink, а также виртуальные файловые системы (ФС), такие,
|
||||||
|
как +/proc+ и +/sys+. Подобные ФС являются лишь программными интерфейсами, и
|
||||||
|
не~предоставляют возможности для долговременного хранения данных (в частности,
|
||||||
|
между перезагрузками системы). Они просто используют классические механизмы
|
||||||
|
работы с файлами для предоставления доступа к различным данным и настройкам.
|
||||||
|
Кроме того, существуют специальные ФС, используемые программами для собственных
|
||||||
|
нужд, в частности, для хранения сегментов разделяемой памяти (shared memory),
|
||||||
|
временных файлов и сокетов. В данной статье мы обсудим все эти разновидности
|
||||||
|
\emph{специальных файловых систем}. Ниже представлен список таких ФС,
|
||||||
|
поддерживаемых в типовых Linux-системах:
|
||||||
|
\begin{itemize}
|
||||||
|
\item +/sys+ предоставляет доступ к драйверам и устройствам, а также
|
||||||
|
некоторым другим параметрам ядра
|
||||||
|
\item +/proc+ дает доступ к информации о выполняемых процессах,
|
||||||
|
настройкам ядра, а также другим параметрам
|
||||||
|
\item +/dev+ отображает файлы устройств (device nodes)
|
||||||
|
\item +/run+ содержит файлы и сокеты, используемые программами
|
||||||
|
\item +/tmp+ хранит временные и часто изменяемые объекты (X)
|
||||||
|
\item +/sys/fs/cgroup+ (и другие файловые системы, смонтированные в
|
||||||
|
подкаталогах этого каталога) позволяют работать с иерархией
|
||||||
|
контрольных групп
|
||||||
|
\item +/sys/kernel/security+, +/sys/kernel/debug+ (X),
|
||||||
|
+/sys/kernel/config+ (X) предоставляют доступ к
|
||||||
|
специализированным механизмам ядра
|
||||||
|
\item +/sys/fs/selinux+ используется для взаимодействия с SELinux
|
||||||
|
\item +/dev/shm+ содержит объекты разделяемой памяти
|
||||||
|
\item +/dev/pts+ обеспечивает доступ к псевдо-TTY устройствам
|
||||||
|
\item +/proc/sys/fs/binfmt_misc+ используется для регистрации в ядре
|
||||||
|
дополнительных бинарных форматов (X)
|
||||||
|
\item +/dev/mqueue+ содержит объекты IPC-механизма mqueue (X)
|
||||||
|
\item +/dev/hugepages+ позволяет программам запрашивать выделение
|
||||||
|
<<гигантских>> страниц памяти (X)
|
||||||
|
\item +/sys/fs/fuse/connections+ обеспечивает доступ к
|
||||||
|
FUSE-соединениям (X)
|
||||||
|
\item +/sys/firmware/efi/efivars+ предоставляет доступ к переменным EFI
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
systemd монтирует все эти файловые системы на ранних стадиях загрузки, даже если
|
||||||
|
они не~указаны явно в +/etc/fstab+. В зависимости от настроек вашего ядра,
|
||||||
|
некоторые из перечисленных выше ФС могут быть недоступны, и наоборот, могут
|
||||||
|
присутствовать другие специальные ФС, не~приведенные в этом списке. Все эти
|
||||||
|
механизмы играют важную роль во взаимодействии ядра с программами и программ
|
||||||
|
между собой. Именно поэтому они подключаются автоматически, безо всякого участия
|
||||||
|
пользователя. Необдуманное вмешательство в их работу (отключение или изменение
|
||||||
|
параметров) может нарушить нормальную работу ваших программ, так как они утратят
|
||||||
|
доступ к необходимым для них интерфейсам.
|
||||||
|
|
||||||
|
В абсолютном большинстве случаев достаточно настроек, используемых по умолчанию.
|
||||||
|
Однако, могут возникнуть ситуации, когда необходимо изменить параметры
|
||||||
|
монтирования специальных ФС, либо полностью отключить монтирование некоторых из
|
||||||
|
них.
|
||||||
|
|
||||||
|
Несмотря на то, что эти ФС по умолчанию отсутствуют в +/etc/fstab+, ничто
|
||||||
|
не~мешает вам их туда добавить. Параметры монтирования, которые вы при этом
|
||||||
|
укажете, будут автоматически применяться к соответствующим ФС. Проще говоря:
|
||||||
|
если вам нужно изменить параметры монтирования для специальных ФС, просто
|
||||||
|
добавьте их в +/etc/fstab+ с указанием соответствующих опций. Кроме параметров
|
||||||
|
монтирования, так можно изменить и сам тип файловой системы. В частности, этот
|
||||||
|
способ позволяет переключить +/tmp+ с +tmpfs+ на физический дисковый раздел.
|
||||||
|
|
||||||
|
Также вы можете полностью отключить монтирование некоторых (но не~всех)
|
||||||
|
специальных систем, если это действительно необходимо. Отключаемые ФС в списке
|
||||||
|
выше отмечены (X). Для их отключения, достаточно замаскировать соответствующий
|
||||||
|
юнит:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl mask dev-hugepages.mount
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
В результате выполнения такой операции, соответствующая ФС больше не~будет
|
||||||
|
монтироваться по умолчанию, начиная со следующей загрузки системы. О том, что
|
||||||
|
такое маскировка юнита, вы можете прочитать в~главе~\ref{sec:off}.
|
||||||
|
|
||||||
|
На всякий случай отметим, что применение к специальным ФС параметров монтирования,
|
||||||
|
указанных в +/etc/fstab+, обеспечивается службой
|
||||||
|
\hreftt{http://www.freedesktop.org/software/systemd/man/systemd-remount-fs.service.html}%
|
||||||
|
{systemd-remount-fs.service}.
|
||||||
|
|
||||||
|
\subsection*{Зачем вы мне все это рассказываете? Я просто хочу убрать tmpfs из
|
||||||
|
/tmp!}
|
||||||
|
|
||||||
|
У вас есть три варианта:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Вы можете отключить любое монтирование в +/tmp+, в результате чего
|
||||||
|
содержимое данного каталога будет храниться на том же разделе, что
|
||||||
|
и корень. Для этого достаточно выполнить команду
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl mask tmp.mount
|
||||||
|
\end{Verbatim}
|
||||||
|
\item Вы можете смонтировать в +/tmp+ обычную файловую систему,
|
||||||
|
размещенную на диске. Для этого достаточно создать
|
||||||
|
соответствующую запись в +/etc/fstab+.
|
||||||
|
\item Если вы хотите оставить в +/tmp+ +tmpfs+, но при этом задать для
|
||||||
|
нее другой размер~--- это тоже делается через внесение в
|
||||||
|
+/etc/fstab+ соответствующей записи, предписывающей монтирование
|
||||||
|
+tmpfs+ в +/tmp+ с нужным вам значением параметра +size=+.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
\section{Запуск служб после появления сети\sfnote{Перевод статьи
|
||||||
|
<<\href{http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget}{Running
|
||||||
|
Services After the Network is up}>> с официального сайта проекта, по состоянию
|
||||||
|
на 2013-01-17 23:22:58 (ревизия \No17).}}
|
||||||
|
|
||||||
|
\emph{Итак, ваша служба настроена на запуск только после достижения цели
|
||||||
|
network.target, однако, несмотря на это, она все равно запускается до появления
|
||||||
|
сети. У вас возникают вопросы: <<Почему так происходит?>> и <<Как это
|
||||||
|
исправить?>>.}
|
||||||
|
|
||||||
|
Цель +network.target+ является systemd-шным аналогом LSB-сущности (facility)
|
||||||
|
\verb+$network+. Определение этой сущности в стандарте
|
||||||
|
\href{http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/facilname.html}%
|
||||||
|
{довольно расплывчато} и оставляет широкий простор для трактовок. Вот примеры
|
||||||
|
некоторых из них:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Все заданные в настройках сетевые интерфейсы переведены в состояние
|
||||||
|
UP и получили IP-адреса.
|
||||||
|
\item Все имеющиеся физические сетевые интерфейсы, на которых
|
||||||
|
зарегистрирована несущая (link beat), получили IP-адреса.
|
||||||
|
Наличие или отсутствие явных настроек роли не~играет.
|
||||||
|
\item Доступен DNS-сервер.
|
||||||
|
\item Доступен некоторый выбранный сервер.
|
||||||
|
\item Доступен некий абстрактный <<интернет>>.
|
||||||
|
\item Все заданные в настройках ethernet-интерфейсы переведены в
|
||||||
|
состояние UP, однако процесс настройки PPP-интерфейсов еще
|
||||||
|
не~начался.
|
||||||
|
\item Активирован некий профиль сетевых настроек, задающий одно из
|
||||||
|
условий выше. В разных профилях могут использоваться разные
|
||||||
|
условия.
|
||||||
|
\item Выполняется некоторое условие (выбор условия определяется
|
||||||
|
физическим расположением системы).
|
||||||
|
\item Настроен как минимум один глобальный адрес IPv4.
|
||||||
|
\item Настроен как минимум один глобальный адрес IPv6.
|
||||||
|
\item Настроен как минимум один глобальный адрес IPv4 или IPv6.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Этот список можно продолжать и дальше. Каждый предложенный в нем вариант можно
|
||||||
|
использовать в качестве критерия появления сети, однако ни~один из них
|
||||||
|
не~подходит в качестве варианта по умолчанию, пригодного для абсолютного
|
||||||
|
большинства задач.
|
||||||
|
|
||||||
|
Современные компьютерные сети живут в очень динамичном ритме: компьютеры
|
||||||
|
перемещаются между сетями, сетевые настройки меняются, устройства подключаются и
|
||||||
|
отключаются, виртуальные сети настраиваются, перенастраиваются и выключаются.
|
||||||
|
Наличие сетевого соединения не~является чем-то постоянным и безусловным. В
|
||||||
|
разные моменты времени компьютер может быть подключен к разным сетям. И это
|
||||||
|
справедливо не~только для мобильных устройств (смартфонов, планшетов и
|
||||||
|
ноутбуков), но и, в определенной мере, для встраиваемых и серверных систем.
|
||||||
|
Программы, которые считают, что сеть является чем-то неизменным и непрерывно
|
||||||
|
доступным, не~могут нормально функционировать в таких условиях. Хорошо
|
||||||
|
написанная программа должна корректно реагировать на изменение состояния сети, и
|
||||||
|
не~унывать в беде. Если нужный ей сервер не~доступен в настоящий момент, она
|
||||||
|
должна не~зависать по тайм-ауту, а пытаться достучаться к нему снова и снова.
|
||||||
|
Если сетевое соединение утрачено, она должна отреагировать на это. Реализовать
|
||||||
|
такое реагирование в коде демона, на самом деле, не~так уж и сложно. Существует
|
||||||
|
множество хорошо известных сетевых служб, которые уже давно поддерживают такую
|
||||||
|
возможность. Подобные службы можно запускать в любой момент, они устойчивы к
|
||||||
|
сбоям, и в любой ситуации работают корректно.
|
||||||
|
|
||||||
|
+network.target+ предназначена для поддержки программ, созданных в
|
||||||
|
предположении, что сеть доступна постоянно (т.е. написанных не~очень аккуратно).
|
||||||
|
Конкретные требования таких программ могут сильно отличаться. Например,
|
||||||
|
IMAP-серверу будет достаточно наличия IP-адреса, на котором можно слушать. В то
|
||||||
|
время как для клиентов сетевых файловых систем требуется требуется доступность и
|
||||||
|
работоспособность сервера, а также, опционально, наличие работоспособного DNS.
|
||||||
|
Таким образом, конкретные требования к +network.target+ сильно зависят от
|
||||||
|
решаемой задачи.
|
||||||
|
|
||||||
|
По соображениям надежности, загрузка системы не~должна зависеть от второстепенных
|
||||||
|
служб. В частности, отсутствие ответа от DHCP-сервера не~должно завешивать
|
||||||
|
процесс загрузки системы (за исключением ситуаций, когда сетевое соединение
|
||||||
|
действительно необходимо для работы системы, например, при загрузке по сети).
|
||||||
|
|
||||||
|
По умолчанию, +network.target+ не~несет какой-либо сакральной смысловой
|
||||||
|
нагрузки. Сама по себе настройка службы на запуск после достижения этой цели
|
||||||
|
не~дает видимого эффекта. Наполнить +network.target+ смыслом должен сам
|
||||||
|
администратор, в зависимости от задачи которую он решает, и от конкретных
|
||||||
|
потребностей тех программ, с которыми ему приходится работать (а эти
|
||||||
|
потребности, в свою очередь, могут зависеть от их настроек). По умолчанию, мы
|
||||||
|
оставили +network.target+ <<пустышкой>>, что позволяет обеспечить максимальную
|
||||||
|
скорость загрузки, и предоставили администратору возможность самостоятельно
|
||||||
|
определить список проверок, который он считает наиболее целесообразным для
|
||||||
|
данной системы.
|
||||||
|
|
||||||
|
\subsection*{Короче, как заставить network.target работать?}
|
||||||
|
|
||||||
|
Конкретный рецепт зависит от решаемой вами задачи и потребностей ваших служб
|
||||||
|
(см. выше). Если вы используете NetworkManager, вы можете задействовать
|
||||||
|
специальную службу +NetworkManager-wait-online.service+:
|
||||||
|
\begin{Verbatim}
|
||||||
|
systemctl enable NetworkManager-wait-online.service
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
Включение этой службы позволит гарантировать, что загрузка продолжится только
|
||||||
|
после того, как все заданные в настройках NM сетевые интерфейсы будут переведены
|
||||||
|
в состояние UP и получат IP-адреса. Максимальное время ожидания~--- 90
|
||||||
|
секунд\footnote{Прим. перев.: В апстримной конфигурации по умолчанию сейчас
|
||||||
|
используется значение 30 секунд. См. параметр +--timeout+ программы +nm-online+
|
||||||
|
в файле настроек службы
|
||||||
|
+/usr/lib/systemd/system/NetworkManager-wait-online.service+.}.
|
||||||
|
Обратите внимание, что включение данной службы может сильно замедлить загрузку.
|
||||||
|
|
||||||
|
Если же такое вариант вас не~устраивает, вы можете подготовить собственный
|
||||||
|
service-файл, запускающий любую заданную вами программу или скрипт. Не~забудьте
|
||||||
|
указать, что он должен быть запущен до достижения цели +network.target+ (при
|
||||||
|
помощи параметра +Before=+). Кроме того, стоит указать зависимость от
|
||||||
|
+network.target+ при помощи директивы +Wants=+\footnote{Прим. перев.: Также
|
||||||
|
не~стоит забывать, что ваша служба сама должна быть кем-то активирована. Это
|
||||||
|
определяется параметром +WantedBy=+ или +RequiredBy=+ секции +[Install]+. Проще
|
||||||
|
всего указать здесь ту же самую +network.target+: в результате, ваша служба и
|
||||||
|
+network.target+ будут взаимно зависеть друг от друга, но при этом
|
||||||
|
+network.target+ будет активирована только после того, как отработает ваша
|
||||||
|
служба. Разница между +WantedBy=+ и +RequiredBy=+ состоит в том, что при
|
||||||
|
использовании Require требуется \emph{успешное} завершение запуска вашей службы.
|
||||||
|
Если он завершится с ненулевым кодом выхода или по сигналу, +network.target+
|
||||||
|
не~будет активирована. В то время как для Want достаточно просто завершения
|
||||||
|
запуска, вне зависимости от успешности. В качестве основы вы можете взять
|
||||||
|
\href{http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/data/NetworkManager-wait-online.service.in}%
|
||||||
|
{апстримный файл} +NetworkManager-wait-online.service+. В завершение,
|
||||||
|
не~забудьте выполнить для своей службы +systemctl enable+.}.
|
||||||
|
|
||||||
|
\subsection*{А что делать нам, разработчикам?}
|
||||||
|
|
||||||
|
Если вы~--- не~администратор, а разработчик сетевой службы, то вам стоит
|
||||||
|
задуматься не~о том, что делать с +network.target+, а о том, как можно исправить
|
||||||
|
вашу службу, чтобы она нормально реагировала на изменение состояния сети. Это
|
||||||
|
позволит порадовать ваших пользователей (когда программа работает без
|
||||||
|
дополнительной возни~--- это не~может не~радовать), а также уменьшит количество
|
||||||
|
сообщений об ошибках (так как ваша программа уже не~будет паниковать по
|
||||||
|
пустякам). Кроме того, системы ваших пользователей будут грузиться быстрее,
|
||||||
|
потому что их уже не~будет задерживать необходимость ожидать появления сети (в
|
||||||
|
случае с медленным DHCP-сервером, прогресс может быть весьма ощутимым).
|
||||||
|
|
||||||
|
Можно предложить несколько подходов к решению этой задачи:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Отслеживайте изменений конфигурации сети при помощи
|
||||||
|
\href{https://www.kernel.org/doc/man-pages/online/pages/man7/rtnetlink.7.html}%
|
||||||
|
{rtnetlink} и реагируйте соответствующим образом. Это наиболее
|
||||||
|
правильный, но далеко не~всегда простой способ.
|
||||||
|
\item Если вы разрабатываете серверное приложение: слушайте только
|
||||||
|
адреса 0.0.0.0 и 127.0.0.1. Оба этих псевдо-адреса должны быть
|
||||||
|
доступны постоянно. Если ваша программа будет слушать только их,
|
||||||
|
ей будут глубоко безразличны изменения конфигурации сети.
|
||||||
|
\item Если вы разрабатываете серверное приложение и вам нужно слушать
|
||||||
|
некий заданный адрес: воспользуйтесь опцией
|
||||||
|
\href{https://www.kernel.org/doc/man-pages/online/pages/man7/ip.7.html}%
|
||||||
|
{IP\_FREEBIND}, доступной на Linux-системах. Она позволит вашей
|
||||||
|
программе слушать даже те адреса, которые не~присвоены локальным
|
||||||
|
сетевым интерфейсам (в данный момент или вообще), что также
|
||||||
|
сделает ваш код устойчивым к изменению сетевой конфигурации.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\section{Моя служба не~может получить приоритет realtime\sfnote{Перевод статьи
|
||||||
|
<<\href{http://www.freedesktop.org/wiki/Software/systemd/MyServiceCantGetRealtime}%
|
||||||
|
{My Service Can't Get Realtime!}>> с официального сайта проекта, по состоянию на
|
||||||
|
2013-01-15 16:54:09 (ревизия \No1).}}
|
||||||
|
|
||||||
|
\emph{Итак, у вас есть служба, которая требует приоритет реального времени
|
||||||
|
(realtime). Однако, когда вы пытаетесь запустить ее на системе, работающей под
|
||||||
|
управлением systemd, ваша служба не~может получить этот приоритет, хотя обладает
|
||||||
|
всеми необходимыми для этого привилегиями. Вы хотите понять, почему это
|
||||||
|
происходит, и как это можно исправить.}
|
||||||
|
|
||||||
|
\subsection*{В чем же дело?}
|
||||||
|
|
||||||
|
По умолчанию, systemd помещает каждую системную службу в свою контрольную группу
|
||||||
|
в иерархии контроллера +cpu+. Такое поведение дает очень полезный эффект: службы
|
||||||
|
с множеством рабочих потоков (например, Apache с сотнями CGI-процессов),
|
||||||
|
получают примерно такую же долю процессорного времени, как и службы с небольшим
|
||||||
|
количеством рабочих потоков (например, MySQL). Проще говоря, процессорное время
|
||||||
|
распределяется уже не~\emph{между процессами}, а \emph{между службами}.
|
||||||
|
|
||||||
|
К сожалению, в настоящее время реализация cpu-контроллера в Linux имеет один
|
||||||
|
существенный недостаток: она требует явного задания realtime-бюджета времени (RT
|
||||||
|
budget) для своих контрольных групп. Если же бюджет группы не~задан, то ее
|
||||||
|
процессы не~смогут получить приоритет реального времени (соответствующая
|
||||||
|
операция будет завершаться с ошибкой +EPERM+~--- <<недостаточные полномочия>>).
|
||||||
|
systemd не~может присваивать такой бюджет \emph{каждой} группе, просто потому,
|
||||||
|
что не~знает, как его правильно делить между ними. Бюджет выдается в абсолютных
|
||||||
|
единицах времени, и их общее количество ограничено. Мы не~можем предложить
|
||||||
|
механизм распределения бюджета, который бы подходил по умолчанию для большинства
|
||||||
|
случаев. Поэтому, в конфигурации по умолчанию, приоритет реального времени
|
||||||
|
недоступен для системных служб.
|
||||||
|
|
||||||
|
\subsection*{Как это исправить?}
|
||||||
|
|
||||||
|
Обойти это ограничение несложно. Существует несколько различных путей:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Можно просто отключить использование cpu-контроллера по умолчанию
|
||||||
|
для системных служб. Для этого, задайте в файле
|
||||||
|
+/etc/systemd/system.conf+ параметр +DefaultControllers=+ равным
|
||||||
|
пустой строке, после чего перезагрузите систему. (Также вы
|
||||||
|
можете отключить контроллер +cpu+ на этапе сборки ядра. systemd
|
||||||
|
не~пытается использовать контроллеры, которые не~поддерживаются
|
||||||
|
ядром.)
|
||||||
|
\item Также вы можете отключить группировку по +cpu+ только для
|
||||||
|
конкретных служб. Для этого отредактируйте конфигурацию службы,
|
||||||
|
добавив параметр +ControlGroup=cpu:/+ в секцию +[Service]+. В
|
||||||
|
результате, процессы данной службы будут помещены не~в
|
||||||
|
собственную контрольную группу (как это делалось по умолчанию),
|
||||||
|
а в корневую контрольную группу иерархии +cpu+. Процессы из
|
||||||
|
корневой группы располагают полным realtime-бюджетом.
|
||||||
|
\item И наконец, вы можете явно выделить своей службе некоторый бюджет.
|
||||||
|
Для этого добавьте в секцию +[Service]+ строку наподобие
|
||||||
|
+ControlGroupAttribute=cpu.rt_runtime_us 500000+. Подробнее о
|
||||||
|
правильном распределении бюджета читайте в
|
||||||
|
\href{http://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt}%
|
||||||
|
{документации к ядру}.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Последние две опции недоступны для SysV-служб. Тем не~менее, вы можете
|
||||||
|
подготовить для них соответствующие service-файлы, которые, помимо упомянутых
|
||||||
|
выше параметров, содержат вызов соответствующего init-скрипта с аргументом
|
||||||
|
+start+ в +ExecStart=+, и с аргументом +stop+~--- в +ExecStop=+.
|
||||||
|
(Также имеет смысл задать для них параметры +RemainAfterExit=1+ и
|
||||||
|
+Type=forking+.)
|
||||||
|
|
||||||
|
Отметим, что все вышесказанное касается только системных служб, и не~затрагивает
|
||||||
|
пользовательские сеансы. По умолчанию, программы пользователя размещаются в
|
||||||
|
корневой группе контроллера +cpu+, и поэтому вышеописанные ограничения их
|
||||||
|
не~касаются.
|
||||||
|
|
||||||
|
Мы надеемся, что в будущем ядро будет исправлено таким образом, чтобы
|
||||||
|
не~требовать явного задания realtime-бюджета для получения приоритета реального
|
||||||
|
времени (а при получении такого приоритета, бюджет процесса должен автоматически
|
||||||
|
выделяться из бюджета ближайшей родительской группы). В идеале, мы хотели бы
|
||||||
|
распространить практику выделения cpu-групп не~только на системные службы, но и
|
||||||
|
на пользовательские сеансы, чтобы уравнять пользователей в правах на
|
||||||
|
процессорное время, вне зависимости от того, сколько процессов запускает каждый
|
||||||
|
конкретный пользователь.
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|
||||||
vim:ft=tex:tw=80:spell:spelllang=ru
|
vim:ft=tex:tw=80:spell:spelllang=ru
|
||||||
|
|||||||
Reference in New Issue
Block a user