Compare commits

...

1 Commits
v8.0 ... v8.1

Author SHA1 Message Date
nnz1024
50c0e1a158 Version v8.1 (2011-12-13 21:05) [AUTO] 2017-08-17 23:05:38 +03:00

113
s4a.tex
View File

@@ -16,6 +16,7 @@ pdfauthor={Lennart Poettering, Sergey Ptashnick}}
% Несколько сокращений
\newcommand{\sectiona}[1]{\section*{#1}\addcontentsline{toc}{section}{#1}}
\newcommand{\hreftt}[2]{\href{#1}{\texttt{#2}}}
\newcommand{\llangl}{\reflectbox{\rotatebox[origin=c]{270}{$\neg$}}}
% Настройка макета страницы
\setlength{\hoffset}{-1.5cm}
\addtolength{\textwidth}{2cm}
@@ -2126,10 +2127,10 @@ systemd?
нескольких экземплярах (по крайней мере, в мире systemd)~--- \emph{fsck},
программа проверки файловой системы, которая запускается по одному экземпляру
на каждое блочное устройство, требующее такой проверки. И наконец, стоит
упомянуть службы с активацией в стиле inetd~--- через сокет, по одному
экземпляру на каждое соединение. В этой статье я попытаюсь рассказать, как в
systemd реализовано управление <<многоэкземплярными>> службами, и какие выгоды
системный администратор может извлечь из этой возможности.
упомянуть службы с активацией в стиле inetd~--- при обращении через сокет, по
одному экземпляру на каждое соединение. В этой статье я попытаюсь рассказать,
как в systemd реализовано управление <<многоэкземплярными>> службами, и какие
выгоды системный администратор может извлечь из этой возможности.
Если вы читали предыдущие статьи из этого цикла, вы, скорее всего, уже знаете,
что службы systemd именуются по схеме \emph{foobar}+.service+, где
@@ -2179,6 +2180,110 @@ RestartSec=0
\href{http://cgit.freedesktop.org/systemd/plain/units/serial-getty@.service.m4}{полную
версию}.)
Этот файл похож на обычный файл конфигурации юнита, с единственным отличием: в
нем используются спецификаторы \%I и \%i. В момент загрузки юнита, systemd
заменяет эти спецификаторы на идентификатор экземпляра службы. В нашем случае,
при обращении к экземпляру +serial-getty@ttyUSB0.service+, они заменяются на
<<+ttyUSB0+>>. Результат этой замены можно проверить, например, запросив
состояние для этой службы:
\begin{Verbatim}[commandchars=\\\{\}]
$ systemctl status serial-getty@ttyUSB0.service
serial-getty@ttyUSB0.service - Getty on ttyUSB0
Loaded: loaded (/lib/systemd/system/serial-getty@.service; static)
Active: active (running) since Mon, 26 Sep 2011 04:20:44 +0200; 2s ago
Main PID: 5443 (agetty)
CGroup: name=systemd:/system/getty@.service/ttyUSB0
\llangl{} 5443 /sbin/agetty -s ttyUSB0 115200,38400,9600
\end{Verbatim}
Собственно, это и есть ключевая идея организации экземпляров служб. Как видите,
systemd предоставляет простой в использовании механизм шаблонов, позволяющих
динамически создавать экземпляры служб. Добавим несколько дополнительных
замечаний, позволяющих эффективно использовать этот механизм:
Вы можете создавать дополнительные экземпляры таких служб, просто добавляя
символьные ссылки в каталоги +*.wants/+. Например, чтобы обеспечить запуск getty
на ttyUSB0 при каждой загрузке, достаточно создать такую ссылку:
\begin{Verbatim}
# ln -s /lib/systemd/system/serial-getty@.service \
/etc/systemd/system/getty.target.wants/serial-getty@ttyUSB0.service
\end{Verbatim}
При этом файл конфигурации, на который указывает ссылка (в нашем случае
+serial-getty@.service+), будет вызван с тем именем экземпляра, которое указанно
в названии этой ссылки (в нашем случае~--- +ttyUSB0+).
Вы не~сможете обратиться к юниту-шаблону без указания идентификатора экземпляра.
В частности, команда +systemctl start serial-getty@.service+ завершится ошибкой.
Иногда возникает необходимость отказаться от использования общего шаблона
для конкретного экземпляра (т.е. конфигурация данного экземпляра настолько
сильно отличается от конфигурации остальных экземпляров данной службы, что
механизм шаблонов оказывается неэффективен). Специально для таких случаев, в
systemd и заложен предварительный поиск файла с именем, точно соответствующим
указанному (прежде чем использовать общий шаблон). Таким образом, вы можете
поместить файл с именем, точно соответствующим полному титулу экземпляра, в
каталог +/etc/systemd/system/+~--- и содержимое этого файла, при обращении
к выбранному экземпляру, полностью перекроет все настройки, сделанные в общем
шаблоне.
В приведенном выше файле, в некоторых местах используется спецификатор +%I+, а
в других~--- +%i+. У вас может возникнуть закономерный вопрос~--- чем они
отличаются? +%i+ всегда точно соответствует идентификатору экземпляра, в то
время, как +%I+ соответствует экранированной (escaped) версии этого
идентификатора. Когда идентификатор не~содержит спецсимволов (например,
+ttyUSB0+). Но имена устройств, например, содержат слеши (<</>>), которые
не~могут присутствовать в имени юнита (и в имени файла на Unix). Поэтому, перед
использованием такого имени в качестве идентификатора устройства, оно должно
быть экранировано~--- <</>> заменяются на <<->>, а большинство других
специальных символов (включая <<->>) заменяются последовательностями вида
+\xAB+, где AB~--- ASCII-код символа, записанный в шестнадцатеричной системе
счисления\footnote{Согласен, этот алгоритм дает на выходе не~очень читабельный
результат. Но этим грешат практически все алгоритмы экранирования. В данном
случае, были использован механизм экранирования из udev, с одним изменением. В
конце концов, нам нужно было выбрать что-то. Если вы собираетесь комментировать
наш алгоритм экранирования~--- пожалуйста, также укажите, где вы живете, чтобы я
мог приехать к вам и раскрасить ваш велосипедный гараж в синий с желтыми
полосами. Спасибо!}\,\footnote{Прим. перев.: В предыдущем примечании автор снова
намекает на Паркинсовский Закон Тривиальности. Действительно, выбор алгоритма
экранирования практически не~влияет ни на работу systemd, ни на управлением им
(файлы/юниты с экранированными именами, как правило либо создаются специальными
программами-генераторами, либо формируются systemd на лету; при выводе состояния
показываются и неэкранированные имена; при вводе команд, как обычно, на
помощь приходит автодополнение оболочки).}. Например, чтобы обратиться
последовательному USB-порту по его адресу на шине, нам нужно использовать имя
наподобие +serial/by-path/pci-0000:00:1d.0-usb-0:1.4:1.1-port0+. Экранированная
версия этого имени~---
+serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0+. +%I+ будет
ссылаться на первую из этих строк, +%i+~--- на вторую. С практической точки
зрения, это означает, что спецификатор +%i+ можно использовать в том случае,
когда надо сослаться на имена других юнитов, например, чтобы описать
дополнительные зависимости (в случае с +serial-getty@.service+, этот
спецификатор используется для ссылки на юнит +dev-%i.device+, соответствующий
одноименному устройству). В то время как +%I+ удобно использовать в командной
строке (+ExecStart+) и для формирования читабельных строк описания. Рассмотрим
работу этих принципов на примере нашего юнит-файла:
\begin{landscape}
\begin{Verbatim}[fontsize=\small]
# systemctl start 'serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0.service'
# systemctl status 'serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0.service'
serial-getty@serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0.service - Serial Getty on serial/by-path/pci-0000:00:1d.0-usb-0:1.4:1.1-port0
Loaded: loaded (/lib/systemd/system/serial-getty@.service; static)
Active: active (running) since Mon, 26 Sep 2011 05:08:52 +0200; 1s ago
Main PID: 5788 (agetty)
CGroup: name=systemd:/system/serial-getty@.service/serial-by\x2dpath-pci\x2d0000:00:1d.0\x2dusb\x2d0:1.4:1.1\x2dport0
5788 /sbin/agetty -s serial/by-path/pci-0000:00:1d.0-usb-0:1.4:1.1-port0 115200 38400 9600
\end{Verbatim}
\end{landscape}
Как видите, в качестве идентификатора экземпляра используется экранированная
версия, в то время как в строке описания и в командной строке +getty+
используется неэкранированная версия. Как и предполагалось.
(Небольшое замечание: помимо +%i+ и +%I+, существует еще несколько
спецификаторов, и большинство из них доступно и в обычных файлах конфигурации
юнитов, а не~только в шаблонах. Подробности можно посмотреть на
\href{http://0pointer.de/public/systemd-man/systemd.unit.html}{странице
руководства}, содержащей полный перечень этих спецификаторов с краткими
пояснениями.)
\end{document}
vim:ft=tex:tw=80:spell:spelllang=ru