Внутреннее устройство Linux
Шрифт:
Идея, заложенная в эту службу, заключается в том, что, когда сетевой клиент подключается к данной службе, она повторяет все, что отправляет клиент. Модуль будет прослушивать TCP порт 22222. Мы назовем его службой эхо-запроса и начнем с модуля сокета, представленного следующим файлом модуля echo.socket:
[Unit]
Description=echo socket
[Socket]
ListenStream=22222
Accept=yes
Обратите внимание на то, что внутри файла модуля нет упоминания о том, какой модуль службы поддерживается
Он называется echo@.service. Эта ссылка составлена на основе соглашения о присвоении имен: если у файла модуля службы такой же префикс, что и у файла .socket (в данном случае echo), команда systemd знает о том, что надо активизировать данный модуль службы, когда в модуле сокета возникает активность. В данном случае команда systemd создает экземпляр echo@.service, когда возникает активность сокета echo.socket.
Вот файл модуля службы echo@.service:
[Unit]
Description=echo service
[Service]
ExecStart=-/bin/cat
StandardInput=socket
примечание
Если вам не нравится неявная активизация модулей на основе префиксов или же вам необходимо создать механизм активизации между двумя модулями с разными префиксами, можно использовать вариант явного присвоения в модуле, который определяет ресурс. Применяйте, например, запись Socket=bar.socket внутри файла foo.service, чтобы модуль bar.socket предоставлял свой сокет службе foo.service.
Чтобы данная служба заработала, необходимо запустить после нее сокет echo.socket:
# systemctl start echo.socket
Теперь можно проверить эту службу, подключившись к локальному порту 22222. Когда приведенная ниже команда telnet установит соединение, наберите что-либо и нажмите клавишу Enter. Служба возвратит вам набранный текст.
$ telnet localhost 22222
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hi there.
Hi there.
Когда захотите закончить, нажмите сочетание клавиш Ctrl+] в самой строке, а затем сочетание клавиш Ctrl+D. Чтобы остановить службу, остановите модуль сокета:
# systemctl stop echo.socket
Экземпляры и передача управления
Поскольку модуль echo@.service поддерживает несколько одновременных экземпляров, в его имени присутствует символ @ (вспомните, что такой символ означает параметризацию). Однако зачем может понадобиться несколько экземпляров? Причина в том, что у вас может оказаться более одного сетевого клиента, подключенного к этой службе в данный момент времени, и каждое соединение должно иметь собственный экземпляр.
В указанном случае модуль службы должен поддерживать несколько
примечание
Для большинства сетевых соединений требуется больше гибкости по сравнению с простым шлюзом стандартного ввода/вывода, поэтому не рассчитывайте на то, что сможете создавать сетевые службы с помощью модулей, подобных описанному здесь echo@.service.
Хотя модуль службы мог бы выполнить всю работу по принятию соединения, он не может содержать в своем имени символ @. Иначе он смог бы полностью контролировать сокет, и команда systemd не стала бы пытаться прослушивать сетевой порт, пока этот модуль службы не завершит работу.
Множество различных ресурсов и параметров передачи управления модулям служб не позволяют составить краткий обзор. К тому же документация к параметрам занимает несколько страниц руководства. Модулям, ориентированным на ресурсы, посвящены страницы systemd.socket(5), systemd.path(5) и systemd.device(5). О модулях служб есть также документ systemd.exec(5), который часто упускают из виду. Он содержит информацию о том, как модуль службы может рассчитывать на получение ресурса после активизации.
6.4.8. Совместимость команды systemd со сценариями System V
Одно свойство, которое отличает команду systemd от других init-систем нового поколения, заключается в том, что эта команда стремится выполнять более полную работу по отслеживанию служб, запущенных сценариями, которые совместимы со стандартом System V. Это работает следующим образом.
1. Сначала команда systemd активизирует модуль runlevel<N>.target, где N является уровнем запуска.
2. Для каждой символической ссылки в файле /etc/rc<N>.d команда systemd идентифицирует сценарий в каталоге /etc/init.d.
3. Команда systemd ассоциирует название сценария с модулем службы (например, для сценария /etc/init.d/foo это будет foo.service).
4. Команда systemd активизирует модуль службы и запускает сценарий с аргументом start или stop, в зависимости от его имени в файле rc<N>.d.
5. Команда systemd пытается ассоциировать любые процессы сценария с модулями служб.