Compare commits

...

3 Commits
v1.0 ... v3.0

Author SHA1 Message Date
nnz1024
01f2aafc02 Version v3.0 (2011-03-22 17:42) [AUTO] 2017-08-17 23:05:37 +03:00
nnz1024
71b6656ebb Version v2.1 (2011-01-11 14:55) [AUTO] 2017-08-17 23:05:37 +03:00
nnz1024
3c9bd24d22 Version v2.0 (2010-12-28 18:18) [AUTO] 2017-08-17 23:05:37 +03:00

300
s4a.tex
View File

@@ -2,12 +2,13 @@
\usepackage{cmap} % Copy-paste из PDF без проблем с кодировкой
\usepackage[utf8]{inputenc}
\usepackage[english,russian]{babel} % Русские переносы и проч.
\usepackage[pdftex]{graphicx,color}
\usepackage{graphicx,color}
\usepackage[T1,T2A]{fontenc}
\usepackage{indentfirst} % Отступ в первом абзаце главы
\usepackage{fancyvrb} % Продвинутые листинги и in-line commands
% listings для данной ситуации, имхо, избыточен
\usepackage{pdflscape}
\usepackage{pdflscape} % Внимание! При выводе в DVI выборочный
% поворот страниц работать не будет, хотя текст будет повернут.
\usepackage[colorlinks,unicode,urlcolor=blue]{hyperref}
% Заполняем поля PDF уже со включенной опцией unicode
\hypersetup{pdftitle={systemd для администраторов},%
@@ -17,9 +18,10 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
% Настройка макета страницы
\setlength{\hoffset}{-1.5cm}
\addtolength{\textwidth}{2cm}
\setlength{\voffset}{-1.5cm}
\addtolength{\textheight}{2cm}
% Настройка in-line commands
\setlength{\voffset}{-2cm}
\addtolength{\textheight}{3cm}
\addtolength{\footskip}{5pt}
% Настройка форматирования in-line commands
\DefineShortVerb{\+}
\VerbatimFootnotes
% И листингов
@@ -32,8 +34,11 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
\begin{document}
\sloppy
\title{systemd для администраторов}
\author{Lennart P\"{o}ttering (author)\\Sergey Ptashnick (russian translation)\\%
\small Licensed under
\author{Lennart P\"{o}ttering (автор)\thanks{Первоисточник (на английском
языке) опубликован на сайте автора: \url{http://0pointer.de/blog/projects}}\\%
Сергей Пташник (русский перевод)\thanks{Актуальная версия перевода
доступна на портале OpenNet: \url{http://wiki.opennet.ru/Systemd}}\\%
\small Данный документ доступен на условиях лицензии
\href{http://creativecommons.org/licenses/by-sa/3.0/legalcode}{CC-BY-SA}}
\maketitle
\tableofcontents%\newpage
@@ -42,7 +47,7 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}~--- это
новая система инициализации дистрибутива Fedora, начиная с
Fedora~14\footnote{Прим. перев.: к сожалению, разработчики Fedora приняли
решение оставить в Fedora~14 в качестве системы инициалиазции по умолчанию
решение оставить в Fedora~14 в качестве системы инициализации по умолчанию
upstart, однако systemd все равно будет включен в этот релиз и может быть
использован в качестве альтернативной системы инициализации}. Помимо Fedora,
systemd также поддерживает и другие дистрибутивы, в частности,
@@ -56,27 +61,27 @@ systemd предоставляет администраторам целый р
мы будем рассматривать ключевые новшества systemd, что может потребовать
несколько более подробного изложения.
\begin{flushright}
Lennart P\"{o}ttering, 23 августа 2010
Lennart P\"{o}ttering, 23 августа 2010~г.
\end{flushright}
\section{Контроль процесса загрузки}
Как правило, во время загрузки Linux по экрану быстро пробегает огромное
количество различных сообщений. Так как мы интенсивно работаем над
параллелизацией и ускорением процесса загрузки, с каждой новой верисей
параллелизацией и ускорением процесса загрузки, с каждой новой версией
systemd эти сообщения будут пробегать все быстрее и быстрее, вследствие чего,
читать их будет все труднее. К тому же, многие пользователи применяют
графические оболочки загрузки (например, Plymouth), полностью скрывающие эти
сообщения. Тем не~менее, информация, которую несут эти сообщения, была и
остается чрезвычайно важной они показывают, успешно ли запустилась каждая
остается чрезвычайно важной~--- они показывают, успешно ли запустилась каждая
служба, или попытка ее запуска закончилась ошибкой (зеленое
\texttt{[~\textcolor{green}{OK}~]} или красное
\texttt{[~\textcolor{red}{FAILED}~]} соответственно). Итак, с ростом скорости
загрузки систем, возникает неприятная ситуация: информация о результатах
запуска служб бывает очень важна, а просматривать ее все тяжелее. systemd
предлагает выход из этой ситуации: он отслеживает и запоминает факты успешного
или неудачного запуска служб на этапе загрузки, а такжи сбои служб во время
или неудачного запуска служб на этапе загрузки, а также сбои служб во время
работы. К таким случая относятся выходы с ненулевым кодом, ошибки
сегментирования и т.п. Введя systemctl status в своей командной оболочке, вы
сегментирования и т.п. Введя +systemctl status+ в своей командной оболочке, вы
можете ознакомиться с состоянием всех служб, как <<родных>> (native) для
systemd, так и классических SysV/LSB служб, поддерживаемых в целях
совместимости:
@@ -179,7 +184,7 @@ JOB = Pending job for the unit.
Обратите внимание на графу ACTIVE, в которой отображается обобщенный статус
службы (или любого другого юнита systemd: устройства, сокета, точки
монтирования~--- их мы рассмотрим подробнее в последующих статьях). Основными
значениями обощенного статуса являются active (служба выполняется) и inactive
значениями обобщенного статуса являются active (служба выполняется) и inactive
(служба не~была запущена). Также существуют и другие статусы. Например,
внимательно посмотрев на листинг выше, вы можете заметить, что служба ntpd
(сервер точного времени) находится в состоянии, обозначенном как maintenance.
@@ -200,12 +205,12 @@ systemd сообщает нам, что ntpd был запущен (с иден
В последующих версиях systemd, мы планируем добавить возможность вызова в
таких ситуациях ABRT (Automated Bug Report Tool), но для этого необходима
соответствующая поддержка со стороны самого ABRT. Соответствующий запрос уже
поддержка со стороны самого ABRT. Соответствующий запрос уже
\href{https://bugzilla.redhat.com/show_bug.cgi?id=622773}{направлен} его
разработчикам, однако пока не~встретил среди них поддержки.
Резюме: использование +systemctl+ и +systemctl status+ представляет современную,
более удобную и эффективную альтернативу разглядыванию быстро пробегающих по
Резюме: использование +systemctl+ и +systemctl status+ является современной,
более удобной и эффективной альтернативой разглядыванию быстро пробегающих по
экрану сообщений в классическом SysV. +systemctl status+ дает возможность
получить развернутую информацию о характере ошибки и, кроме того, в отличие
от сообщений SysV, показывает не~только ошибки при запуске, но и ошибки,
@@ -216,7 +221,7 @@ systemd сообщает нам, что ntpd был запущен (с иден
процессов обычно весьма значительно. Понять, откуда взялся и что делает тот
или иной процесс, становится все сложнее и сложнее. Многие службы используют
сразу несколько рабочих процессов, и это отнюдь не~всегда можно легко
распознать по выводу команды ps. Встречаются еще более сложные ситуации,
распознать по выводу команды +ps+. Встречаются еще более сложные ситуации,
когда демон запускает сторонние процессы~--- например, веб-сервер выполняет
CGI-программы, а демон cron~--- команды, предписанные ему в crontab.
@@ -225,9 +230,9 @@ CGI-программы, а демон cron~--- команды, предписа
полностью. В частности, процессы, родители которых умирают раньше их самих,
становят потомками PID~1 (процесса init), что сразу затрудняет процесс
выяснения их происхождения. Кроме того, процесс может избавиться от связи с
родителем через две последовательные операции +fork()+ (В целом, эта возможность
родителем через две последовательные операции +fork()+ (в целом, эта возможность
признается нужной и полезной, и является частью используемого в Unix подхода
к разработке демонов.) Также, не~будем забывать, что процесс легко может
к разработке демонов). Также, не~будем забывать, что процесс легко может
изменить свое имя посредством +PR_SETNAME+, или задав значение
+argv[0]+, что также усложняет процесс его опознания\footnote{Прим.
перев.: стоит отметить, что перечисленные ситуации могут возникнуть не~только
@@ -236,7 +241,7 @@ CGI-программы, а демон cron~--- команды, предписа
взломанном сервере процесс-бэкдор маскируется под нормального демона, меняя
себе имя, скажем, на httpd}.
systemd предоставляет простой путь для решения обсуждаемой задачи. Запуская
systemd предлагает простой путь для решения обсуждаемой задачи. Запуская
очередной новый процесс, systemd помещает его в отдельную контрольную группу
с соответствующим именем. Контрольные группы Linux предоставляют очень
удобный инструмент для иерархической структуризации процессов: когда
@@ -247,13 +252,13 @@ systemd предоставляет простой путь для решения
процесса, вне зависимости от того, сколько раз он форкался и переименовывал
себя~--- имя его контрольной группы невозможно спрятать или изменить. Кроме
того, при штатном завершении родительской службы, будут завершены и все
порожденные ею процессы, как бы они ни пытались сбежать. С systemd уже
порожденные ею процессы, как бы они ни~пытались сбежать. С systemd уже
невозможна ситуация, когда после остановки web-сервера, некорректно
форкнувшийся CGI-процесс продолжает исполняться вплоть до последних секунд
работы системы.
В этой статье мы рассмотрим две простых команды, которые позволят вам
наглядно увидеть схему взаимоотношений systemd и порожденных им процессов.
наглядно оценить схему взаимоотношений systemd и порожденных им процессов.
Первая из этих команд~--- все та же +ps+, однако на этот раз в ее параметры
добавлено указание выводить сведения по контрольным группам, а также другую
интересную информацию:
@@ -380,14 +385,14 @@ $ ps xawf -eo pid,user,cgroup,args
27285 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-salut
27297 lennart name=systemd:/user/lennart/1 /usr/libexec/geoclue-yahoo
\end{Verbatim}
(Данный листинг был сокращен за счет удаления из него строк, относящихся к
потокам ядра, так как они никак не~относятся к обсуждаемой нами теме.)
(Данный листинг был сокращен за счет удаления из него строк, описывающих
потоки ядра, так как они никак не~относятся к обсуждаемой нами теме.)
\end{landscape}
Обратите внимание на третий столбец, показывающий имя контрольной группы,
которое systemd присваивает каждому процессу. Например, процесс +udev+
находится в группе +name=systemd:/systemd-1/sysinit.service+. В эту группу
помещаются процессы, запущенные службой +sysinit.service+, которая запускается
входят процессы, порожденные службой +sysinit.service+, которая запускается
на ранней стадии загрузки.
Вы можете очень сильно упростить себе работу, если назначите для
@@ -398,9 +403,9 @@ alias psc='ps xawf -eo pid,user,cgroup,args'
---~теперь для получения исчерпывающей информации по процессам достаточно будет
нажать всего четыре клавиши.
Альтернативый способ получить ту же информацию~--- воспользоваться утилитой
Альтернативный способ получить ту же информацию~--- воспользоваться утилитой
+systemd-cgls+, входящей в комплект поставки systemd. Она отображает иерархию
контрольных групп в виде превдографической диаграммы-дерева:
контрольных групп в виде псевдографической диаграммы-дерева:
\begin{landscape}
\begin{Verbatim}[fontsize=\small]
@@ -564,11 +569,11 @@ $ systemd-cgls
systemd именует группы в соответствии с названиями служб. Например, из
приведенного листинга нетрудно понять, что служба системного аудита
+auditd.service+ порождает три отдельных процесса: +auditd+,
+audisp+ и +sedispatch+.
+audispd+ и +sedispatch+.
Внимательно посмотрев на листинг, можно заметить, что некоторые процессы
Наиболее внимательные читатели, вероятно, уже заметили, что некоторые процессы
помещены в группу +/user/lennart/1+. Дело в том, что systemd занимается
отслежванием и группировкой не~только процессов, относящихся к системным
отслеживанием и группировкой не~только процессов, относящихся к системным
службам, но и процессов, запущенных в рамках пользовательских сеансов. В
последующих статьях мы обсудим этот вопрос более подробно.
@@ -588,14 +593,14 @@ shell-скрипты, как правило, отличается низкой
Впрочем, нельзя не~упомянуть, что эти скрипты являются очень гибким
инструментом (ведь, по сути, это всего лишь код, который можно модифицировать
как угодно). С другой стороны, многие задачи, возникающие при работе со
службами, бывает довольно тяжело решить средствами shell-скриптов. К таким
задачам относятся: огранизация параллельного исполнения, корректное
службами, довольно тяжело решить средствами shell-скриптов. К таким
задачам относятся: организация параллельного исполнения, корректное
отслеживание процессов, конфигурирование различных параметров среды исполнения
процесса. systemd обеспечивает совместимость с init-скриптами, однако, с учетом
описанных выше их недостатков, более правильным решением будет использование
штатных service-файлов systemd для всех установленных в системе служб. Стоит
отметить что, в отличие от init-скриптов, которые часто приходится
модифицировать при переносе из одного дистриубтива в другой, один и тот же
модифицировать при переносе из одного дистрибутива в другой, один и тот же
service-файл будет работать в любом дистрибутиве, использующем systemd (а таких
дистрибутивов с каждым днем становится все больше и больше). Далее мы вкратце
рассмотрим процесс преобразования SysV init-скрипта в service-файл systemd.
@@ -615,7 +620,7 @@ Bug Reporting Tool, службы, занимающейся сбором crash du
Начнем с того, что прочитаем исходный скрипт (неожиданный ход, правда?) и
выделим полезную информацию из груды хлама. Практически у всех init-скриптов
большая часть кода является чисто вспомогательной, и мало чем отличается от
б\'{о}льшая часть кода является чисто вспомогательной, и мало чем отличается от
одного скрипта к другому. Как правило, при создании новых скриптов этот код
просто копируется из уже существующих (разработка в стиле copy-paste). Итак,
в исследуемом скрипте нас интересует следующая информация:
@@ -633,23 +638,23 @@ Bug Reporting Tool, службы, занимающейся сбором crash du
комментариев соответствующих init-скриптов. Изначально эта
схема была введена именно для того, чтобы стандартизировать
init-скрипты во всех дистрибутивах. Однако разработчики
многих дистрибутивов не~считают нужным точное исполнение
требований LSB, и поэтому формы представления метаданных в
многих дистрибутивов не~считают нужным точно исполнять
требования LSB, и поэтому формы представления метаданных в
различных дистрибутивах могут отличаться. Вследствие этого,
при переносе init-скрипта из одного дистрибутива в другой,
скрипт приходится модифицировать. Например, демон пересылки
почты при описании зависимостей может именоваться
+MTA+ или +smtpdaemon+ (Fedora), +smtp+
(openSUSE), +mail-transport-agent+ (Debian и Ubuntu),
+mail-transfer-agent+. Таким образом,
стандарт LSB не~справляется с поставленной задачей},
+mail-transfer-agent+. Таким образом, можно утверждать, что
стандарт LSB не~справляется с возложенной на него задачей},
содержащий информацию о зависимостях. systemd, базирующийся
на идеях socket-активации, обычно не~требует явного описания
зависимостей (либо требует самого минимального описания).
Заметим, что основополагающие принципы systemd, включая
socket-активацию, рассмотрены в статье
\href{http://0pointer.de/blog/projects/systemd.html}{Rethinking
PID 1}, в которой systemd был впервые представлен широкой
PID~1}, в которой systemd был впервые представлен широкой
публике. Ее русский перевод можно прочитать здесь:
\href{http://tux-the-penguin.blogspot.com/2010/09/systemd.html}{часть~1},
\href{http://tux-the-penguin.blogspot.com/2010/09/systemd-ii.html}{часть~2}.
@@ -673,7 +678,7 @@ Bug Reporting Tool, службы, занимающейся сбором crash du
(команды +echo+), разбор входных параметров (монструозный блок
+case+).
На основе приведенной выше полезной информации, мы можем написать следующий
На основе приведенной выше информации, мы можем написать следующий
service-файл:
\begin{Verbatim}
[Unit]
@@ -690,7 +695,7 @@ WantedBy=multi-user.target
Рассмотрим этот файл поподробнее.
Секция +[Unit]+ содежит самую общую информацию о службе. Не будем
Секция +[Unit]+ содержит самую общую информацию о службе. Не~будем
забывать, что systemd управляет не~только службами, но и многими другими
объектами, в частности, устройствами, точками монтирования, таймерами и т.п.
Общее наименование всех этих объектов~--- юнит (unit). Одноименная секция
@@ -708,10 +713,10 @@ WantedBy=multi-user.target
использующими устаревшие реализации демона системного лога}. Эта информация,
как мы помним, была указана в LSB-заголовке исходного init-скрипта. В нашем
конфигурационном файле мы указываем зависимость от демона системного лога при
помощи директивы +After+, ссылающейся на юнит +syslog.taget+. Это
помощи директивы +After+, указывающей на юнит +syslog.taget+. Это
специальный юнит, позволяющий ссылаться на любую реализацию демона системного
лога, независимо от используемой программы (например, rsyslog или syslog-ng)
и типа активации (как обычной службы или через log-сокет). Подробнее о таки
и типа активации (как обычной службы или через log-сокет). Подробнее о таких
специальных юнитах можно почитать
\href{http://0pointer.de/public/systemd-man/systemd.special.html}{страницу}
официальной документации. Обратите внимание, что директива +After+, в
@@ -726,8 +731,8 @@ systemd будет предписывать запуск как демона с
+Requires+, задающей жесткую зависимость между юнитами.
Следующая секция, +[Service]+, содержит информацию о службе. Сюда включаются
настройки, относящие именно к службам, но не~к другим типа юнитов. В нашем
случае, таких настроек две: +ExecStart+ определяет расположение бинарника
настройки, относящие именно к службам, но не~к другим типам юнитов. В нашем
случае, таких настроек две: +ExecStart+, определяющая расположение бинарника
демона и аргументы, с которыми он будет вызван (в нашем случае они
отсутствуют), и +Type+, позволяющая задать метод, по которому systemd определит
окончание периода запуска службы. Традиционный для Unix метод демонизации
@@ -745,7 +750,7 @@ systemd считает службу запущенной с момента за
котором он используется в большинстве дистрибутивов семейства Red Hat, а
именно, многопользовательский режим без запуска графической оболочки}.
Директива +WantedBy+ никак не~влияет на уже работающую службу, но она
играет важную роль при выполнении команды systemctl enable, задавая, в каких
играет важную роль при выполнении команды +systemctl enable+, задавая, в каких
условиях должен активироваться устанавливаемый юнит. В нашем примере, служба
abrtd будет активироваться при переходе в состояние +multi-user.target+,
т.е., при каждой нормальной загрузке\footnote{Обратите внимание, что режим
@@ -755,7 +760,7 @@ abrtd будет активироваться при переходе в сос
образом, все службы, запускаемые в режиме +multi-user.target+, будут
также запускаться и в режиме +graphical.target+} (к <<ненормальным>>
можно отнести, например, загрузки в режиме +emergency.target+, который
является аналогом первого уровня исполнения В классической SysV).
является аналогом первого уровня исполнения в классической SysV).
Вот и все. Мы получили минимальный рабочий service-файл systemd. Чтобы
проверить его работоспособность, скопируем его в
@@ -771,7 +776,8 @@ abrtd будет активироваться при переходе в сос
Приведенный выше service-файл является практический точным переводом
исходного init-скрипта, и он никак не~использует широкий спектр возможностей,
предоставляемых systemd. Ниже приведен немного улучшенный вариант:
предоставляемых systemd. Ниже приведен немного улучшенный вариант этого же
файла:
\begin{Verbatim}
[Unit]
@@ -788,14 +794,14 @@ WantedBy=multi-user.target
\end{Verbatim}
Чем же новый вариант отличается от предыдущего? Ну, прежде всего, мы уточнили
описание службы. Однако, ключевым изменением является замена +Type+ с +forking+
описание службы. Однако, ключевым изменением является замена значения +Type+ с +forking+
на +dbus+ и связанные с ней изменения: добавление имени службы в шине D-Bus
(директива +BusName+) и задание полонительных аргументов abrtd <<+-d -s+>>. Но
(директива +BusName+) и задание дополнительных аргументов abrtd <<+-d -s+>>. Но
зачем вообще нужна эта замена? Каков ее практический смысл? Чтобы ответить на
этот вопрос, мы снова возращаемся к демонизации. В ходе этой операции, процесс
этот вопрос, мы снова возвращаемся к демонизации. В ходе этой операции процесс
дважды форкается и отключается от всех терминалов. Это очень удобно при запуске
демона через скрипт, но в случае использования таких продвинутых систем
инициализации, как systemd, такое поведение не~дает никаких преимуществ, но
инициализации, как systemd, подобное поведение не~дает никаких преимуществ, но
вызывает неоправданные задержки. Даже если мы оставим в стороне вопрос скорости
загрузки, останется такой важный аспект, как отслеживание состояния служб.
systemd решает и эту задачу, контролируя работу службы и при необходимости
@@ -805,14 +811,14 @@ systemd решает и эту задачу, контролируя работу
службу, либо активировать какой-либо заранее заданный юнит. Операция
демонизации несколько затрудняет решение этих задач, так как обычно довольно
сложно найти связь демонизированного процесса с исходным (собственно, смысл
демонизации как раз и сводится к уничтожению этой связи) и, сооветственно, для
демонизации как раз и сводится к уничтожению этой связи) и, соответственно, для
systemd сложнее определить, какой из порожденных в рамках данной службы
процессов является основным. Чтобы упростить для него решение этой задачи, мы и
воспользовались типом запуска +dbus+. Он подходит для всех служб, которые в
конце процесса инициализации регистрируют свое имя на шине D-Bus\footnote{В
настоящее время практически все службы дистрибутива Fedora после запуска
регистрируется на шине D-Bus}. ABRTd относится к ним. С новыми настройками,
systemd запусит процесс abrtd, который уже не~будет форкаться (согласно
systemd запустит процесс abrtd, который уже не~будет форкаться (согласно
указанным нами ключам <<+-d -s+>>), и в качестве момента окончания периода
запуска данной службы systemd будет рассматривать момент регистрации имени
+com.redhat.abrt+ на шине D-Bus. В этом случае основным для данной службы будет
@@ -830,7 +836,7 @@ systemd запусит процесс abrtd, который уже не~буде
падения. Или, например, добавив +OOMScoreAdjust=-500+, мы попросим ядро сберечь
эту службу, даже если OOM Killer выйдет на тропу войны. А если мы добавим
строчку +CPUSchedulingPolicy=idle+, процесс abrtd будет работать только в те
моменты, когда система больше ничем не~занята, что позволит не создавать помех
моменты, когда система больше ничем не~занята, что позволит не~создавать помех
для процессов, активно использующих CPU.
За более подробным описанием всех опций настройки, вы можете обратиться к
@@ -846,28 +852,28 @@ service-файлы. Но, к счастью, <<проблемных>> скрип
\section{Убить демона}
Убить системного демона нетрудно, правда? Или\ldots все не~так просто?
Убить системного демона нетрудно, правда? Или\ldots{} все не~так просто?
Если ваш демон функционирует как один процесс, все действительно очень просто.
Вы командуете +killall rsyslogd+, и демон системного лога останавливается.
Впрочем, этот метод не~вполне корректен, так как он действует не~только на
самого демона, но и на другие процессы с тем же именем. Иногда подобное
поведение может привести к неприятным последствиям. Более правильным будет
использование pid-файла: +kill \$(cat /var/run/syslogd.pid)+. Вот, вроде
бы, и все, что вам нужно\ldots Или мы упускаем еще что-то?
использование pid-файла: +kill $(cat /var/run/syslogd.pid)$+. Вот, вроде
бы, и все, что вам нужно\ldots{} Или мы упускаем еще что-то?
Действительно, мы забываем про одну простую вещь: существуют службы, такие, как
Apache, crond, atd, которые по роду служебной дейятельности должны запускать
дочерние процессы. Это могут быть совершенно посторонние, указаанные
Действительно, мы забываем одну простую вещь: существуют службы, такие, как
Apache, crond, atd, которые по роду служебной деятельности должны запускать
дочерние процессы. Это могут быть совершенно посторонние, указанные
пользователем программы (например, задачи cron/at, CGI-скрипты) или полноценные
серверные процессы (например, Apache workers). Когда вы убиваете основной
процесс, он может остановить все дочерние процессы. А может и не~остановить. В
самом деле, если служба функционирует в штатном режиме, ее обычно останавливают
специальной командой stop. К прямому вызову kill администратор, как правило,
командой +stop+. К прямому вызову +kill+ администратор, как правило,
прибегает только в аварийной ситуации, когда служба работает неправильно и
может не~среагировать на стандартную команду остановки. Таким образом, убив,
например, основной сервер Apache, вы можете получить от него в наследство
работающие CGI-скрипты, причем их родителем автоматически станет PID 1 (init),
работающие CGI-скрипты, причем их родителем автоматически станет PID~1 (init),
так что установить их происхождение будет не~так-то просто.
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} спешит к нам
@@ -903,10 +909,10 @@ Apache, crond, atd, которые по роду служебной дейяте
В некоторый случах возникает необходимость отправить сигнал именно основному
процессу службы. Например, используя +SIGHUP+, мы можем заставить демона
перечитать файлы конфигурации. Разумеется, вспомогательным процессам
передавать HUP в этом случае совершенно необязательно. Для решения этой
задачи вполbb неплохо подойдет и классический метод с pid-файлом, однако у
systemd и на этот случай есть просто решение, избавляющее вас от
перечитать файлы конфигурации. Разумеется, передавать HUP вспомогательным процессам
в этом случае совершенно необязательно. Для решения подобной
задачи неплохо подойдет и классический метод с pid-файлом, однако у
systemd и на этот случай есть простое решение, избавляющее вас от
необходимости искать нужный файл:
\begin{Verbatim}
@@ -925,9 +931,9 @@ systemd и на этот случай есть просто решение, из
После прочтения сказанного выше у вас может возникнуть вопрос: в чем разница
между +systemctl kill+ и +systemctl stop+? Отличие состоит в том,
что +kill+ просто отправляет сигнал заданному процессу, в то время как
stop действует по <<официально>> определенному методу, вызывая команду,
+stop+ действует по <<официально>> определенному методу, вызывая команду,
определенную в параметре +ExecStop+ конфигурации службы. Обычно команды
stop бывает вполне достаточно для остановки службы, и к +kill+
+stop+ бывает вполне достаточно для остановки службы, и к +kill+
приходится прибегать только в крайних случаях, например, когда служба
<<зависла>> и не~реагирует на команды.
@@ -940,4 +946,158 @@ stop бывает вполне достаточно для остановки с
инструментов, позволяющих корректно отправить сигнал службе в целом, а
не~отдельному процессу.
\section{Три уровня выключения}
В \href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} существует
три уровня (разновидности) действий, направленных на прекращение работы службы
(или любого другого юнита):
\begin{itemize}
\fvset{gobble=3}
\item Вы можете \emph{остановить} службу, то есть прекратить
выполнение уже запущенных процессов службы. При этом
сохраняется возможность ее последующего запуска, как ручного
(через команду +systemctl start+), так и автоматического (при
загрузке системы, при поступлении запроса через сокет или
системную шину, при срабатывании таймера, при подключении
соответствующего оборудования и т.д.). Таким образом,
остановка службы является временной мерой, не~дающей никаких
гарантий на будущее.
В качестве примера рассмотрим остановку службы NTPd
(отвечающей за синхронизацию времени по сети):
\begin{Verbatim}
systemctl stop ntpd.service
\end{Verbatim}
Аналогом этой команды в классическом SysV init является
\begin{Verbatim}
service ntpd stop
\end{Verbatim}
Заметим, что в Fedora~15, использующей в качестве системы
инициализации systemd, в целях обеспечения обратной
совместимости допускается использование классических
SysV-команд, и systemd будет корректно воспринимать их.
В~частности, вторая приведенная здесь команда будет эквивалентна
первой.
\item Вы можете \emph{отключить} службу, то есть отсоединить ее от всех
триггеров активации. В результате служба уже не~будет
автоматически запускаться ни~при загрузке системы, ни~при
обращении к сокету или адресу на шине, ни~при подключении
оборудования, и т.д. Но при этом сохраняется возможность
<<ручного>> запуска службы (командой +systemctl start+).
Обратите внимание, что при отключении уже запущенной службы, ее
выполнение в текущем сеансе не~останавливается~--- это нужно
сделать отдельно, иначе процессы службы будут работать до
момента выключения системы (но при следующем включении,
разумеется, уже не~запустятся).
Рассмотрим отключение службы на примере все того же NTPd:
\begin{Verbatim}
systemctl disable ntpd.service
\end{Verbatim}
В классических SysV-системах аналогичная команда будет иметь
вид
\begin{Verbatim}
chkconfig ntpd off
\end{Verbatim}
Как и в предыдущем случае, в Fedora~15 вторая из этих команд
будет действовать аналогично первой.
Довольно часто приходится сочетать действия отключения и
остановки службы~--- такая комбинированная операция
гарантирует, что уже исполняющиеся процессы службы будут
прекращены, и служба больше не~будет запускаться автоматически
(но может быть запущена вручную):
\begin{Verbatim}
systemctl disable ntpd.service
systemctl stop ntpd.service
\end{Verbatim}
Подобное сочетание команд используется,
например, при деинсталляции пакетов в Fedora.
Обратите внимание, что отключение службы является перманентной
мерой, и действует вплоть до явной отмены соответствующей
командой. Перезагрузка системы не~отменяет отключения службы.
\item Вы можете \emph{заблокировать} (замаскировать) службу. Действие
этой операции аналогично отключению, но дает более сильный
эффект. Если при отключении отменяется только возможность
автоматического запуска службы, но сохраняется возможность
ручного запуска, то при блокировке исключаются обе эти
возможности. Отметим, что использование данной опции при
непонимании принципов ее работы может привести к трудно
диагностируемым ошибкам.
Тем не~менее, рассмотрим пример блокировки все той же службы NTPd:
\begin{Verbatim}
ln -s /dev/null /etc/systemd/system/ntpd.service
systemctl daemon-reload
\end{Verbatim}
Итак, блокировка сводится к созданию символьной ссылки
с именем соответствующей службы, указывающей на +/dev/null+.
После такой операции служба не~может быть запущена ни~вручную,
ни~автоматически. Символьная ссылка создается в каталоге
+/etc/systemd/system/+, а ее имя должно соответствовать имени
файла описания службы из каталога +/lib/systemd/system/+ (в
нашем случае +ntpd.service+).
Заметим, что systemd читает файлы конфигурации из обоих этих
каталогов, но файлы из +/etc+ (управляемые системным
администратором) имеют приоритет над файлами из +/lib+ (которые
управляются пакетным менеджером). Таким образом, созание
символьной ссылки (или обычного файла)
+/etc/systemd/system/ntpd.service+ предотвращает чтение
штатного файла конфигурации +/lib/systemd/system/ntpd.service+.
В выводе +systemctl status+ заблокированные службы отмечаются
словом +masked+. Попытка запустить такие службы командой
+systemctl start+ завершится ошибкой.
В рамках классического SysV init, штатная реализация такой
возможности отсутствует. Похожий эффект может быть
достигнут с помощью <<костылей>>, например, путем добавления
команды +exit 0+ в начало init-скрипта. Однако, подобные решения
имеют ряд недостатков, например, потенциальная возможность
конфликтов с пакетным менеджером (при очередном обновлении
исправленный скрипт может быть просто затерт соответствующим
файлом из пакета).
Стоит отметить, что блокировка службы, как и ее отключение,
является перманентной мерой\footnote{Прим. перев.: подробно
описав принцип работы блокировки службы (юнита), автор забывает
привести практические примеры ситуаций, когда эта возможность
оказывается полезной.
В частности, иногда бывает необходимо
полностью предотвратить запуск службы в любой ситуации. При этом
не~стоит забывать, что в post-install скриптах пакетного
менеджера или, скажем, в~заданиях cron, вместо
+systemctl try-restart+ (+service condrestart+) может быть
ошибочно указано +systemctl restart+ (+service restart+), что
является прямым указанием на запуск службы, если она еще
не~запущена. Вследствие таких ошибок, отключенная служба может
<<ожить>> в самый неподходящий момент.
Другой пример~---
ограничение возможностей непривилегированного пользователя при
управлении системой. Даже если такому пользователю делегировано
(через механизмы sudo или PolicyKit) право на использование
+systemctl+, это еще не~означает, что он сможет запустить
заблокированную службу~--- права на выполнение +rm+ (удаление
блокирующей символьной ссылки) выдаются отдельно}.
\end{itemize}
После прочтения изложенного выше, у читателя может возникнуть вопрос: как
отменить произведенные изменения? Что ж, ничего сложного тут нет:
+systemctl start+ отменяет действия +systemctl stop+, +systemctl enable+
отменяет действие +systemctl disable+, а +rm+ отменяет действие +ln+.
\end{document}
vim:ft=tex:tw=80:spell:spelllang=ru