Systemd запуск скрипта от пользователя. Демоническая сила: Изучаем systemd, ulatencyd, relayd и fscd. Включение и отключение служб

Как и ранее, чтобы запустить какой-то скрипт при загрузке системы, вы можете поместить его в файл /etc/rc.d/rc.local . Однако стоит учесть специфику запуска этого скрипта в systemd.

service-файл отвечающего за него юнита выглядит следующим образом:

$ cat /lib/systemd/system/rc-local.service Description=/etc/rc.d/rc.local Compatibility After=network.target Type=forking ExecStart=/etc/rc.d/rc.local start TimeoutSec=0 RemainAfterExit=yes SysVStartPriority=99

Отсюда видно, во-первых, что файл /etc/rc.d/rc.local обязан быть исполняемым.

А во-вторых, видно, что сервис rc-local имеет зависимость только от цели network.target . Параметр SysVStartPriority=99 отвечает только за приоритет по сравнению с другими sysVinit-скриптами, которых в Fedora становится все меньше. С учетом параллельной загрузки это означает, что скрипт, который вы разместите в файле rc.local может быть запущен слишком рано , например, до старта нужных сервисов. Поэтому, если вы разместите в этом файле скрипты перезапуска апача, то, с большой вероятностью, они не сработают.

В версиях до Fedora 17, не было зависимости от network.target , так что, там этот скрипт запускался практически в самом начале.

С помощью systemd-юнита

Более естественный для systemd способ запускать скрипты - это создание своего собственного юнита.

Просто создайте файл /etc/systemd/system/my_stuff.service со следующим текстом:

Description=Run my stuff Requires=network.target After=network.target Type=oneshot RemainAfterExit=True ExecStart=/some/script --with-some-parameters ExecStart=/some/other/script WantedBy=multi-user.target

Здесь Requires - указывает цель, после которой необходимо запустить сервис, After означает, что сеть должна быть полностью запущена к моменту старта, WantedBy - цель, для которой запускается сервис. В ExecStart должен быть указан полный путь к скрипту или исполняемому файлу, поскольку переменная PATH не используется.

multi-user.target - это аналог init 3 в sysVinit. Подробнее о реализации runlevel-ов в systemd, можно прочесть по ссылке .

В такой конфигурации скрипты будут запускаться сразу после запуска сети и старта всех интерфейсов. Однако systemd позволяет гораздо более гибкую настройку. Например, для выполнения скриптов после запуска графического DM можно использовать After: systemd-user-sessions.service

Небольшой пример: После появления облачного хранилища Яндекс.Диск, захотелось автоматически монтировать его в файловую систему через davfs2 (с заранее положенными логином и паролем в /etc/davfs2/secrets). Прописывание в fstab не дало результатов, как и прописывание в rc.local, поскольку в Fedora 16 оба они обрабатывались ещё до поднятия сети. А вот создание модуля по вышеприведённому образцу решило проблему.

Дополнительно

Для диагностики сервиса используйте команду

Systemctl status rc-local.service

или загляните в файл /var/log/boot.log (он появится если в параметрах загрузки убрать quiet , см.

systemd - это новый демон инициализации Linux-систем, который в последующем должен прийти на смену классическому демону SysV initd. Основные задачи, которые он призван решить - это, во-первых, ускорение загрузки системы за счёт максимального увеличения количества параллельно запускающихся сервисов, во-вторых, улучшение управляемости системы за счёт использования специфических возможностей, предоставляемых ядром Linux, в-третьих, унификация общесистемных настроек и максимальное обобщение кода запуска различных сервисов. По крайней мере, такие ощущения у меня сложились после ознакомления с документацией.

Хочу поблагодарить Сергея Пташника за отличный перевод документации на systemd: systemd для администратора от автора самой системы, Леннарта Потеринга. Также хочется сказать спасибо за многочисленные примечания к документации, которые всегда оказываются к месту. Эта и последующие мои заметки существенным образом основываются именно на этой документации, а точнее, на её PDF-версии .

1. Установка systemd

Установить systemd довольно просто. Сначала поставим пакет:
# apt-get install systemd И пропишем использование systemd в настройках ядра Linux. Для этого откроем файл с настройками загрузчика GRUB 2:
# vi /etc/default/grub И добавим в настройку GRUB_CMDLINE_LINUX_DEFAULT дополнительную опцию init=/lib/systemd/systemd. После редактирования у меня эта опция стала выглядеть следующим образом:
GRUB_CMDLINE_LINUX="video=VGA-1:640x480 video=TV-1:640x480 rootfstype=ext4 init=/lib/systemd/systemd" Теперь применим изменения, сгенерировав новый файл конфигурации загрузчика:
# update-grub Теперь можно перезагрузить систему, чтобы начать использовать systemd:
# shutdown -r now 2. Решение проблем

2.1. Локализация текстовой консоли

Первая проблема, с которой я столкнулся - это ошибка запуска скрипта console-cyrillic. Этот скрипт должен запускаться при активной текстовой консоли, а systemd запускает все скрипты инициализации асинхронно, в результате чего этот скрипт отрабатывает к моменту, когда уже запущен X-сервер. Как следствие - в консоли вместо русских букв отображаются квадраты, нельзя переключить раскладку и переключиться обратно в графический сеанс.

Console-cyrillic - это устаревший пакет, который остался в моей системе с тех времён, когда я её устанавливал (а было это во времена Etch). Этот пакет имеется в новых версиях Debian и до сих пор поддерживается, однако более универсальной альтернативой для него являются пакеты console-setup и keyboard-configuration. В статье Отображение русского в консоли Ubuntu 11.04 Natty описаны необходимые действия по их настройке.

Установим необходимые пакеты:
# apt-get install console-setup keyboard-configuration Если по каким-то причинам конфигуратор пакетов не был запущен при установке пакетов, можно запустить конфигурирование пакетов принудительно:
# dpkg-reconfigure console-setup # dpkg-reconfigure keyboard-configuration Вообще, в systemd предусмотрены новые файлы конфигурации для настройки текстовой консоли, но в моей системе эти настройки не сработали.

2.2. Сохранение системного времени в аппаратные часы BIOS

При смене настроек времени, по каким-то причинам, не происходит сохранение времени в часах BIOS. Сохранить текущее системное время в аппаратные часы можно с помощью команды:
# hwclock -w Реальное время, которое будет сохранено в часы BIOS, зависит от третьей строчки файла /etc/adjtime. В случае строки UTC будет сохраняться время по Гринвичу, в случае строки LOCAL - будет сохранено время текущего часового пояса.

Нужно отметить, что начиная с Wheezy, настройка UTC удалена из файла /etc/default/rcS и вместо неё теперь используется настройка из файла /etc/adjtime: release-notes: utc/local timezone no longer in /etc/default/rcS .

Корень же проблемы кроется в том, что я использую openntpd, а не ntpd. В случае работающего ntpd в ядре системы включается сохранение текущего системного времени в аппаратный таймер каждые 11 минут. Разработчики systemd посчитали, что этого достаточно. Если же ntpd не используется, то нельзя определить, какие из часов точнее - аппаратные или системные, поэтому и нет смысла предпочитать одни часы другим. В случае необходимости, пользователь должен сам настроить часы вручную необходимым образом.

Для решения этой проблемы я решил написать свой service-файл для демона openntpd. Содержимое service-файла /etc/systemd/system/openntpd.service:
Description=openntpd After=network.target Type=simple ExecStart=/usr/sbin/ntpd -dsf /etc/openntpd/ntpd.conf ExecStartPost=/bin/chown ntpd /var/lib/openntpd/ntpd.drift ExecStop=/sbin/hwclock -w WantedBy=multi-user.target Теперь нужно остановить уже запущенный экземпляр openntpd, сообщить systemd о том, что его конфигурация изменилась:
# systemctl stop openntpd.service # systemctl daemon-reload Включить только что созданный файл сервиса в автозагрузку и запустить openntpd:
# systemctl enable openntpd.service # systemctl start openntpd.service 3. Управление сервисами

Systemd, в отличие от inetd, умеет самостоятельно отслеживать все процессы, порождённые сервисом. Для этого используются так называемые контрольные группы процессов - cgroups. Каждый сервис запускается с собственным идентификатором группы. Все дополнительные процессы, порождаемые в рамках сервиса, так же получают этот идентификатор. Благодаря этому отпадает необходимость в использовании PID-файлов для управления сервисом. Также, благодаря контрольным группам, процессы, порождённые сервисом, никогда не теряются. Например, CGI-процесс будет остановлен вместе с веб-сервером, даже если веб-сервер не позаботится о его остановке и не поместит идентификатор процесса в PID-файл. Процессы пользователей тоже помещаются в отдельную контрольную группу, и отслеживаются подсистемой logind, пришедшей на смену ConsoleKit.

Вторая важная особенность systemd заключается в том, что он обладает собственной системой журналирования, которая называется journald. Эта система агрегирует информацию из разных источников и привязывает её к сервисам. В одном месте с привязкой к сервису собираются сообщения ядра, сообщения процессов, отправленные через syslog, сообщения, отправленные с помощью собственного API journald и сообщения, отправленные процессом на стандартный вывод - STDOUT и на стандартный поток для диагностических сообщений - STDERR. Также systemd отслеживает коды завершения процессов. Благодаря этому, всю диагностическую информацию сервиса можно просматривать в одном месте и удобно диагностировать неисправности.

systemctl - просмотр статусов сервисов. Если вывод команды не перенаправляется куда-либо, а попадает на консоль, то для просмотра статусов сервисов автоматически запускается программа-пейджер, обычно это less,
systemctl status openntpd.service - подробный просмотр статуса указанного сервиса (openntpd),
systemctl status --follow openntpd.service - просмотр статуса указанного сервиса (openntpd) с выводом сообщений от сервиса в процессе их поступления. У этой опции есть более короткий аналог - -f, который в моей системе по каким-то причинам не заработал. Возможно дело в том, что опция -f имеет ещё второе значение - --force и systemctl не умеет определять, какая именно из опций имеется в виду,
systemctl status -n10 openntpd.service - просмотр статуса указанного сервиса (openntpd) с выводом 10 последних сообщений сервиса,
systemctl reset-failed - сброс всех статусов завершения, отображаемых по команде просмотра статуса сервиса,
systemd-cgls - просмотр иерархии контрольных групп процессов (нечто подобное можно получить при помощи команды ps xawf -eo pid,user,cgroups,args),
systemctl daemon-reload - перезагрузка конфигурации systemd,
systemctl start openntpd.service - запуск указанного сервиса (openntpd), аналогично update-rc.d openntpd start для SysV initd,
systemctl stop openntpd.service - остановка указанного сервиса (openntpd), аналогично update-rc.d openntpd stop для SysV initd,
systemctl restart openntpd.service - перезапуск указанного сервиса (openntpd),
systemctl enable openntpd.service - включение запуска указанного сервиса (openntpd) при загрузке системы, аналогично update-rc.d openntpd enable для SysV initd,
systemctl disable openntpd.service - отключение запуска указанного сервиса (openntpd) при загрузке системы, аналогично update-rc.d openntpd disable для SysV initd,
systemctl mask openntpd.service - запрет запуска указанного сервиса (openntpd), его даже будет нельзя запустить вручную,
systemctl unmask openntpd.service - разрешение запуска указанного сервиса (openntpd), его можно будет запустить вручную, также будет разрешён запуск при загрузке системы, если он был настроен,
systemctl kill openntpd.service - отправка сигнала (по умолчанию отправляется сигнал SIGTERM) всем процессам в контрольной группе сервиса (openntpd),
systemctl kill -s SIGKILL openntpd.service - отправка сигнала SIGKILL всем процессам в контрольной группе сервиса (openntpd). Можно также использовать сокращённое название сигнала - KILL,
systemctl kill -s HUP --kill-who=main crond.service - отправка сигнала SIGHUP главному процессу контрольной группы сервиса (crond). Этот пример заставит crond перечитать файл конфигурации, при этом задания, запущенные crond этот сигнал не получат и продолжат нормальную работу,
systemctl help openntpd.service - просмотр документации сервиса (не работает в Debian Wheezy),
systemd-analyze blame - вывод списка сервисов, отсортированного по убыванию времени, потраченного на их запуск. Команда может быть полезной для поиска узких мест в процессе инициализации системы,
systemd-analyze plot > plot.svg - вывод временнОй диаграммы в формате SVG, иллюстрирующей последовательность (и параллельность) запуска сервисов.

4. Новые файлы конфигурации системы

Systemd вводит ряд новых файлов конфигурации для общесистемных настроек. Предполагается, что эти файлы со временем станут стандартными и вытеснят файлы конфигурации системы, специфичные для разных дистрибутивов. Пока же этого не произошло, systemd будет использовать файлы конфигурации дистрибутивов, если новые файлы отсутствуют.

Кроме того, поскольку теперь все сервисы будут запускаться с помощью service-файлов, отпадает необходимость в использовании файлов, включаемых в shell-скрипты. Это файлы, располагающиеся в каталогах /etc/default (семейство Debian) и /etc/sysconfig (семейство RedHat). Поскольку в service-файлах ориентироваться намного проще, чем в shell-скриптах, нет необходимости выносить настройки сервисов в отдельные файлы - все необходимые настройки можно вписать прямо в service-файл.

Перечислим новые файлы конфигурации, вводимые systemd:

/etc/hostname - сетевое имя системы,
/etc/vconsole.conf - настройки шрифта системной консоли и раскладки клавиатуры,
/etc/locale.conf - языковые настройки системы,
/etc/modules-load.d/*.conf - каталог для перечисления модулей ядра, которые нужно принудительно загрузить при загрузке системы,
/etc/sysctl.d/*.conf - каталог для настроек параметров ядра, дополняет классический файл /etc/sysctl.conf,
/etc/tmpfiles.d/*.conf - каталог для управления настройками временных файлов,
/etc/binfmt.d/*.conf - каталог для регистрации форматов исполняемых файлов, например форматов Java, Mono, WINE,
/etc/os-release - файл с идентификатором дистрибутива и его версии,
/etc/machie-id - файл с постоянным уникальным идентификатором системы,
/etc/machie-info - файл с описательным сетевым именем системы. Здесь же настраивается значок системы, который будет отображаться в графических оболочках. Файл обслуживается демоном systemd-hostnamed.

5. Подсистема журналирования journald

Как уже было сказано, systemd вводит новую систему журналирования, которая собирает информацию из разных источников (сообщения ядра, сообщения, отправленные в syslog, на стандартный вывод STDOUT и на стандартный поток диагностических сообщений STDERR) в одном месте. Эта система не заставляет отказываться от стандартного демона журналирования syslog - можно пользоваться обеими системами журналирования параллельно.

Journald использует для хранения журнальной информации два каталога:
/run/log/journal - каталог с кольцевым буфером последних сообщений,
/var/log/journal - каталог с постоянным хранением всех сообщений.

По умолчанию используется только первый каталог, а для включения постоянного хранения всех сообщений второй каталог нужно создать вручную (в Debian Wheezy этот каталог создаётся автоматически, при установке systemd, а первый каталог не используется):
# mkdir -p /var/log/journald После этого можно, но совершенно не обязательно, удалить стандартный демон журналирования rsyslog или ng-syslog.

Настройки демона journald в Debian Wheezy хранятся в файле /etc/systemd/systemd-journald.conf . В частности, там можно задать настройки сжатия файла журнала, задать лимит размера файлов журнала, настроить дублирование сообщений в системную консоль или в демон syslog.

Пользователь root и пользователи из группы adm имеют доступ ко всем сообщениям в журнале, а обычные пользователи - только к сообщениям, сгенерированным их процессами.

Для просмотра сообщений из журнала в Debian Wheezy можно воспользоваться командой systemd-journalctl (в руководстве указана команда journalctl):
systemd-journalctl - просмотр всех сообщений. Как и в случае systemctl, если вывод команды никуда не перенаправляется, а попадает на консоль, для более удобного просмотра сообщений автоматически запускается программа-пейджер, обычно less,
systemd-journalctl -f - просмотр сообщений в процессе их поступления,
systemd-journalctl -n10 - просмотр 10 последних сообщений,
systemd-journalctl -b - просмотр сообщений, сгенерированных с момента загрузки системы (не работает в Debian Wheezy),
systemd-journalctl -b -p err - просмотр сообщений, сгенерированных с момента загрузки системы и имеющих приоритет error или выше (не работает в Debian Wheezy),
systemd-journalctl --since=yesterday - просмотр всех сообщений, сгенерированных со вчерашнего дня (не работает в Debian Wheezy),
systemd-journalctl --since=2012-10-15 --until="2012-10-16 23:59:59" - просмотр всех сообщений, сгенерированных 15 и 16 октября 2012 года (не работает в Debian Wheezy),
systemd-journalctl -u httpd --since=00:00 --until=09:30 - просмотр всех сообщений, сгенерированных пользователем httpd сегодня с полуночи до полдесятого (не работает в Debian Wheezy),
systemd-journalctl /dev/sdc - просмотр всех сообщений, упоминающих диск sdc (не работает в Debian Wheezy),
systemd-journalctl /usr/sbin/vpnc - просмотр всех сообщений от процессов /usr/sbin/vpnc (не работает в Debian Wheezy),
systemd-journalctl /usr/sbin/vpnc /usr/sbin/dhclient - просмотр всех сообщений от процессов /usr/sbin/vpnc и /usr/sbin/dhclient, объединённый и отсортированный по времени (не работает в Debian Wheezy),

Кроме простого просмотра текстовых сообщений имеется возможность просматривать метаданные, которые journald самостоятельно добавляет к каждой записи в журнале. Чтобы увидеть эти поля, достаточно воспользоваться следующей опцией, переключающей формат вывода данных:
systemd-journalctl -o verbose - выводит вместе с сообщением из журнала все сопутствующие сообщению метаданные в удобном для восприятия человеком виде. Другие доступные форматы: export - тот же самый формат verbose, но без отступов, json - вывод в формате JSON, cat - вывод только текста сообщений без каких-либо дополнительных данных.

Названия полей, начинающиеся со знака подчёркивания, можно использовать для фильтрации сообщений. Журнал индексируется по всем полям, поэтому поиск выполняется быстро. Примеры фильтрации сообщений по метаданным:
systemd-journalctl _UID=70 - вывод всех сообщений от процессов пользователя с идентификатором 70,
systemd-journalctl _UID=70 _UID=71 - вывод всех сообщений от процессов пользователей с идентификаторами 70 и 71. Указание одноимённых полей автоматически подразумевает операцию логического ИЛИ,
systemd-journalctl _HOSTNAME=epsilon _COMM=avahi-daemon - вывод всех сообщений от процессов с именем avahi-daemon, работающих на компьютере с именем epsilon. В данном случае указаны разные поля, поэтому подразумевается операция логического И,
systemd-journalctl _HOSTNAME=theta _UID=70 + _HOSTNAME=epsilon _COMM=avahi-daemon - вывод сообщений, соответствующих любому из двух фильтров, объединённых знаком +. Знак + указывает явную операцию логического ИЛИ, которая имеет более низкий приоритет, чем И,
systemd-journalctl -F _SYSTEMD_UNIT - вывод всех значений поля _SYSTEMD_UNIT, имеющихся в журнале. Полученные значения можно использовать для фильтрации интересующих записей (не работает в Debian Wheezy).

Systemd – это система инициализации и системный менеджер, который становится новым стандартом для Linux-машин. Споры о продуктивности systemd по сравнению с традиционными системами инициализации SysV ведутся до сих пор, тем не менее, эту систему планируют внедрить большинство дистрибутивов, а многие уже сделали это.

Изучение инструментов и демонов systemd и умение работать с ними поможет вам лучше оценить мощность, гибкость и другие возможности системы или, по крайней мере, справиться с минимальными трудностями.

Данный мануал научит вас работать с командой systemctl, главным инструментом управления системы инициализации systemd. Вы узнаете, как управлять сервисами, проверять состояние и работать с конфигурационными файлами.

Управление сервисами

Основная цель init-системы – инициализировать компоненты, которые должны запускаться после загрузки ядра Linux (традиционно они называются «пользовательскими» компонентами). Система инициализации также используется для управления сервисами и демонами сервера. Имея это в виду, начнем знакомство с systemd с простых операций управления сервисами.

В systemd целью большинства действий являются юниты – ресурсы, которыми systemd может управлять. Юниты делятся на категории по типам ресурсов, которые они представляют. Юниты определяются в так называемых юнит-файлах. Тип каждого юнита можно определить по суффиксу в конце файла.

Для задач управления сервисами предназначены юнит-файлы с суффиксом.service. Однако в большинстве случаев суффикс.service можно опустить, так как система systemd достаточно умна, чтобы без суффикса определить, что нужно делать при использовании команд управления сервисом.

Запуск и остановка сервиса

Чтобы запустить сервис systemd, используйте команду start. Если вы работаете не в сессии пользователя root, вам нужно использовать sudo, поскольку эта команда повлияет на состояние операционной системы:

sudo systemctl start application.service

Как уже говорилось ранее, systemd знает, что для команд управления сервисами нужно искать файлы *.service, поэтому эту команду можно ввести так:

sudo systemctl start application

Вышеуказанный формат можно использовать в повседневной работе, но в мануале для ясности мы будем использовать суффикс.service.

Чтобы остановить сервис, достаточно ввести команду stop:

sudo systemctl stop application.service

Перезапуск и перезагрузка

Чтобы перезапустить сервис, используйте restart:

sudo systemctl restart application.service

Если указанное приложение может перезагрузить свои конфигурационные файлы (без перезапуска), можно использовать reload:

sudo systemctl reload application.service

Если вы не знаете, может ли сервис перезагрузить свои файлы, используйте команду reload-or-restart. Она перезагрузит сервис, а если это невозможно – перезапустит его.

sudo systemctl reload-or-restart application.service

Включение и отключение сервисов

Приведенные выше команды необходимы при работе с сервисом в текущей сессии. Чтобы добавить сервис в автозагрузку systemd, его нужно включить.

Для этого существует команда enable:

sudo systemctl enable application.service

Это создаст символическую ссылку на копию файла сервиса (обычно в /lib/systemd/system или /etc/systemd/system) в точке на диске, где systemd ищет файлы для автозапуска (обычно /etc/systemd/system/some_target.target.want, подробнее об этом — дальше в руководстве).

Чтобы убрать сервис из автозагрузки, нужно ввести:

sudo systemctl disable application.service

Имейте в виду, что включение сервиса не запускает его в текущей сессии. Если вы хотите запустить сервис и включить его в автозагрузку, вам нужно запустить команды start и enable.

Проверка состояния сервиса

Чтобы проверить состояние сервиса, введите:

systemctl status application.service

Эта команда выведет состояниесервиса, иерархию групп и первые несколько строк лога.

Например, при проверке состояния сервера Nginx вы можете увидеть такой вывод:

nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
Main PID: 495 (nginx)
CGroup: /system.slice/nginx.service
├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
└─496 nginx: worker process
Jan 27 19:41:23 desktop systemd: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd: Started A high performance web server and a reverse proxy server.

Это предоставляет обзор текущего состояния приложения, уведомляет вас о любых проблемах и любых действиях, которые могут потребоваться в дальнейшем.

Существуют также методы проверки конкретных состояний. Например, чтобы проверить, активен ли данный юнит (запущен ли он), вы можете использовать команду is-active:

systemctl is-active application.service

Это отобразит текущее состояние юнита, обычно это active или inactive. Код завершения будет «0», если юнит активен, что упрощает процесс анализа.

Чтобы узнать, включен ли юнит, вы можете использовать команду is-enabled:

systemctl is-enabled application.service

Эта команда сообщит, включен ли сервис, и снова определит код завершения как «0» или «1» в зависимости от результата.

Третья команда позволяет определить, находится ли юнит в состоянии сбоя. Это указывает на то, что возникла проблема с запуском рассматриваемого юнита:

systemctl is-failed application.service

Команда вернет active, если юнит работает правильно, и failed, если случилась ошибка. Если юнит был остановлен намеренно, команда может вернуть unknown или inactive. Код завершения «0» означает, что произошел сбой, а «1» указывает на любое другое состояние.

Обзор состояния системы

Ранее мы рассмотрели команды, необходимые для управления отдельными сервисами, но они не очень полезны для изучения текущего состояния системы. Существует несколько команд systemctl, которые предоставляют эту информацию.

Просмотр списка текущих юнитов

Чтобы запросить список текущих юнитов systemd, используйте команду list-units:

systemctl list-units

Эта команда покажет список всех юнитов, которые в настоящее время существуют в системе systemd. Результат будет выглядеть примерно так:

UNIT LOAD ACTIVE SUB DESCRIPTION
atd.service loaded active running ATD daemon
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
dbus.service loaded active running D-Bus System Message Bus
dcron.service loaded active running Periodic Command Scheduler
dkms.service loaded active exited Dynamic Kernel Modules System
[email protected] loaded active running Getty on tty1
. . .

В выводе есть такие столбцы:

  • UNIT – название юнита systemd.
  • LOAD – сообщает, была ли конфигурация юнита обработана systemd. Конфигурация загруженных юнитов хранится в памяти.
  • ACTIVE – сводное состояние юнита. Обычно это позволяет быстро определить, успешно ли запущен текущий юнит.
  • SUB: состояние более низкого уровня, которое сообщает подробную информацию об устройстве. Это часто зависит от типа юнита, состояния и фактического метода, в котором запущен юнит.
  • DESCRIPTION – краткое описание функций юнита.

Поскольку команда list-units показывает по умолчанию только активные юниты, все вышеперечисленные записи будут показывать loaded в столбце LOAD и active в столбце ACTIVE. Такой формат является поведением systemctl по умолчанию при вызове без дополнительных команд, поэтому вы увидите то же самое, если вы вызываете systemctl без аргументов:

С помощью systemctl можно запрашивать различную информацию путем добавления флагов. Например, чтобы увидеть все юниты, которые загрузила (или попыталась загрузить) система systemd, независимо от того, активны ли они в данный момент, вы можете использовать флаг -all:

systemctl list-units --all

Эта команда сообщит о юнитах, которые загрузила или попыталась загрузить система systemd, независимо от их текущего состояния. После запуска некоторые юниты становятся неактивными, а юниты, которые пыталась загрузить systemd, не были найдены на диске.

Вы можете использовать другие флаги для фильтрации результатов. Например, флаг —state= можно использовать для определения состояний LOAD, ACTIVE или SUB. Флаг —all нужно оставить, чтобы система отображала неактивные юниты:

systemctl list-units --all --state=inactive

Еще один популярный фильтр – это —type=. Он позволяет отфильтровать юниты по типу. К примеру, чтобы запросить только активные юниты, можно ввести:

systemctl list-units --type=service

Список юнит-файлов

Команда list-units отображает только юниты, которые система systemd попыталась обработать и загрузить в память. Поскольку systemd избирательно читает только те юнит-файлы, которые кажутся ей необходимыми, список не будет включать все доступные юнит-файлы. Чтобы просмотреть список всех доступных юнит-файлов (включая те, что systemd не пыталась загрузить), используйте команду list-unit-files.

systemctl list-unit-files

Юниты являются представлениями ресурсов, о которых знает systemd. Поскольку systemd не обязательно читает все определения юнитов, она представляет только информацию о самих файлах. Вывод состоит из двух столбцов: UNIT FILE и STATE.

UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
dev-hugepages.mount static
dev-mqueue.mount static
proc-fs-nfsd.mount static
proc-sys-fs-binfmt_misc.mount static
sys-fs-fuse-connections.mount static
sys-kernel-config.mount static
sys-kernel-debug.mount static
tmp.mount static
var-lib-nfs-rpc_pipefs.mount static
org.cups.cupsd.path enabled
. . .

Обычно столбец STATE содержит значения enabled, disabled, static или masked. В этом контексте static означает, что в юнит-файле нет раздела install, который используется для включения юнита. Таким образом, эти юниты невозможно включить. Обычно это означает, что юнит выполняет одноразовое действие или используется только как зависимость другого юнита и не должен запускаться сам по себе.

Управление юнитами

Теперь вы знаете, как работать с сервисами и отображать информацию о юнитах и юнит-файлах, о которых знает systemd. Получить более конкретную информацию о юнитах можно с помощью некоторых дополнительных команд.

Отображение юнит-файла

Чтобы отобразить юнит-файл, который загрузила systemd, вы можете использовать команду cat (была добавлена в версии systemd 209). Например, чтобы увидеть юнит-файл демона планирования atd, можно ввести:

systemctl cat atd.service
Description=ATD daemon
Type=forking
ExecStart=/usr/bin/atd
WantedBy=multi-user.target

На экране вы увидите юнит-файл, который известен текущему запущенному процессу systemd. Это может быть важно, если вы недавно изменяли файлы модулей или если вы переопределяете некоторые параметры в фрагменте юнит-файла (об этом поговорим позже).

Отображение зависимостей

Чтобы просмотреть дерево зависимостей юнита, используйте команду:

systemctl list-dependencies sshd.service

Она отобразит иерархию зависимостей, с которыми системе необходимо иметь дело, чтобы запустить этот юнит. Зависимости в этом контексте – это те юниты, которые требуются для работы других юнитов, которые находятся выше в иерархии.

sshd.service
├─system.slice
└─basic.target
├─microcode.service
├─rhel-autorelabel-mark.service
├─rhel-autorelabel.service
├─rhel-configure.service
├─rhel-dmesg.service
├─rhel-loadmodules.service
├─paths.target
├─slices.target
. . .

Рекурсивные зависимости отображаются только для юнитов.target, которые указывают состояния системы. Чтобы рекурсивно перечислить все зависимости, добавьте флаг —all.

Чтобы показать обратные зависимости (юниты, зависящие от указанного элемента), вы можете добавить в команду флаг —reverse. Также полезными являются флаги —before и —after, они отображают юниты, которые зависят от указанного юнита и запускаются до или после него.

Проверка свойств юнита

Чтобы увидеть низкоуровневые свойства юнита, вы можете использовать команду show. Это отобразит список свойств указанного юнита в формате ключ=значение.

systemctl show sshd.service
Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .

Чтобы отобразить одно из свойтсв, передайте флаг –р и укажите имя свойства. К примеру, чтобы увидеть конфликты юнита sshd.service, нужно ввести:

systemctl show sshd.service -p Conflicts
Conflicts=shutdown.target

Маскировка юнитов

Systemd может блокировать юнит (автоматически или вручную), создавая симлинк на /dev/null. Это называется маскировкой юнитов и выполняется командой mask:

sudo systemctl mask nginx.service

Теперь сервис Nginx не будет запускаться автоматически или вручную до тех пор, пока включена маскировка.

Если вы проверите list-unit-files, вы увидите, что сервис отмечен как masked:

systemctl list-unit-files
. . .
kmod-static-nodes.service static
ldconfig.service static
mandb.service static
messagebus.service static
nginx.service masked
quotaon.service static
rc-local.service static
rdisc.service disabled
rescue.service static
. . .

Если вы попробуете запустить сервис, вы получите такое сообщение:

sudo systemctl start nginx.service
Failed to start nginx.service: Unit nginx.service is masked.

Чтобы раскрыть (разблокировать) юнит и сделать его доступным, используйте unmask:

sudo systemctl unmask nginx.service

Это вернет сервис в его прежнее состояние.

Редактирование юнит-файлов

Хотя конкретный формат юнит-файлов не рассматривается в данном руководстве, systemctl предоставляет встроенные механизмы для редактирования и изменения юнит-файлов. Эта функциональность была добавлена в systemd версии 218.

Команда edit по умолчанию открывает сниппет юнит-файла:

sudo systemctl edit nginx.service

Это будет пустой файл, который можно использовать для переопределения или добавления директив в определение юнита. В каталоге /etc/systemd/system будет создан каталог, который содержит имя устройства с суффиксом.d. Например, для nginx.service будет создан каталог nginx.service.d.

Внутри этого каталога будет создан сниппет с именем override.conf. Когда юнит загружается, systemd объединит в памяти сниппет для переопределения с остальным юнит-файлом. Директивы сниппета будут иметь приоритет над теми, что указаны в исходном юнит-файле.

Если вы хотите отредактировать весь юнит-файл вместо создания сниппета, вы можете передать флаг —full:

sudo systemctl edit --full nginx.service

Это загрузит текущий юнит-файл в редактор, где его можно будет изменить. Когда редактор закроется, измененный файл будет записан в /etc/systemd/system и будет иметь приоритет над определением юнита системы (обычно он находится где-то в /lib/systemd/system).

Чтобы удалить все сделанные вами дополнения, удалите каталог конфигурации.d или измененный файл сервиса из /etc/systemd/system. Например, чтобы удалить сниппет, можно ввести:

sudo rm -r /etc/systemd/system/nginx.service.d

Чтобы удалить полный отредактированный файл, введите:

sudo rm /etc/systemd/system/nginx.service

После удаления файла или каталога нужно перезагрузить процесс systemd, чтобы система больше не пыталась ссылаться на эти файлы и вернулась к использованию системных копий. Для этого введите:

sudo systemctl daemon-reload

Изменение уровней запуска

Цели – это специальные юнит-файлы, которые описывают уровни системы или точки синхронизации. Как и другие юниты, файлы целей можно определить по суффиксу. В данном случае используется суффикс.target. Сами по себе цели ничего не делают, вместо этого они используются для группировки других юнитов.

Цели можно использовать, чтобы привести систему в определенное состояние. Подобным образом другие системы инициализации используют уровни запуска. Они используются как ссылки, когда доступны определенные функции, что позволяет указать желаемое состояние вместо настройки отдельных юнитов, необходимых для создания этого состояния.

Например, есть цель swap.target, которая используется для того, что чтобы сообщить, что swap готов к использованию. Юниты, которые являются частью этого процесса, могут синхронизироваться с этой целью при помощи директив WantedBy= или RequiredBy=. Юниты, которым нужен своп, могут указывать это условие через спецификации Wants=, Requires= или After=.

Проверка и настройка целей по умолчанию

Процесс systemd имеет цель по умолчанию, которую он использует при загрузке системы. Обеспечение ряда зависимостей этой единственной цели приводит систему в желаемое состояние. Чтобы найти цель по умолчанию, введите:

systemctl get-default
multi-user.target

Если вы хотите установить другую цель по умолчанию, вы можете использовать set-default. Например, если у вас установлен графический рабочий стол и вы хотите, чтобы система загружала его по умолчанию, вы можете соответствующим образом изменить цель:

sudo systemctl set-default graphical.target

Список доступных целей

Просмотреть список доступных целей можно с помощью команды:

systemctl list-unit-files --type=target

В отличие от уровней запуска, одновременно можно включать несколько целей. Активная цель указывает, что systemd будет пытаться запустить все юниты, привязанные к этой цели, и не попытается их отключить. Чтобы увидеть все активные цели, введите:

systemctl list-units --type=target

Изоляция целей

Можно запустить все юниты, связанные с целью, и остановить все юниты, которые не являются частью дерева зависимостей. Для этого используется команда isolate. Она похожа на изменение уровня запуска в других системах инициализации.

Например, если вы работаете в графической среде, где активна цель graphical.target, вы можете отключить графическую систему и перевести систему в состояние многопользовательской командной строки, изолировав multi-user.target. Поскольку graphical.target зависит от multi-user.target, но не наоборот, все графические юниты будут остановлены.

Вы можете взглянуть на зависимости изолируемой цели, прежде чем выполнять эту процедуру, чтобы убедиться, что вы не останавливаете жизненно важные сервисы:

systemctl list-dependencies multi-user.target

Если вас все устраивает, можете изолировать цель:

sudo systemctl isolate multi-user.target

Сокращения

Существуют цели, определенные для важных событий, таких как выключение или перезагрузка. systemctl также предлагает несколько сокращений для быстрого вызова.

К примеру, чтобы перевести систему в режим отладки, можно ввести просто rescue вместо isolate rescue.target:

sudo systemctl rescue

Это обеспечит дополнительную функциональность – оповестит всех пользователей системы о событии.

Чтобы остановить систему, вы можете использовать команду halt:

sudo systemctl halt

Чтобы начать полное завершение работы, вы можете использовать команду poweroff:

sudo systemctl poweroff

Перезапуск можно начать с помощью команды reboot:

sudo systemctl reboot

Эти команды сообщат пользователям системы о событиях, чего не сделает стандартная команда. Обратите внимание, большинство машин используют более короткие команды для этих операций, чтобы они работали правильно с systemd.

Например, чтобы перезагрузить систему, вы можете ввести просто:

Заключение

Теперь вы знакомы с основными механизмами systemctl и знаете, как управлять системой инициализации с помощью этого инструмента.

Хотя systemctl работает в основном с процессом systemd, в системе systemd есть другие компоненты, которые контролируются другими утилитами. К примеру, для управления логированием и пользовательскими сеансами используются отдельные демоны и утилиты (journald/journalctl и logind/loginctl соответственно).

Полностью вошло в хранилище testing. Начиная с версии (25-1) systemd имеет .

Чтобы установить systemd запустите:

# apt-get update # apt-get install systemd

Вам также необходимо ядро со следующими включенными параметрами:

  • CONFIG_DEVTMPFS=y
  • CONFIG_CGROUPS=y
  • CONFIG_AUTOFS4_FS=
  • CONFIG_IPV6=, опционально, но очень рекомендуется
  • CONFIG_FANOTIFY=y, опционально, требуется для systemd readahead. Доступен в ядре Linux >= 2.6.37-rcX. Должен быть активирован для ядра Debian Linux ().

Начиная с v8 cgroupfs монтируется в /sys/fs/cgroup. Для этого требуется ядро Linux >= 2.6.36 или бэкпортирование этого патча .

Пример (для rsyslog : Ручная активация сервиса после инсталляции):

# systemctl enable rsyslog.service Вывод: ln -s "/lib/systemd/system/rsyslog.service" "/etc/systemd/system/multi-user.target.wants/rsyslog.service"

Известные проблемы и способы их решения

Issue #1: sysvinit vs. systemd-sysv

sysvinit является текущей по умолчанию системой инициализации в Debian и помечен как "Essential" пакет. Это означает, что инструменты управления пакетами откажутся удалить или заменить пакет если только не принудительно. Кроме того, при выполнении dist-upgrades основные пакеты станут предпочтительнее и будут вновь установлены. Для получения большей информации см.chapters "3.8 Essential packages" and "5.6.9 Essential"

Пакет systemd-sysv package имеет в составе /sbin/init (как символьную ссылку на /bin/systemd) и следовательно, конфликтует с пакетом sysvinit .

Решение #1: Не устанавливать systemd-sysv , изменить строку grub (Kernel command line) добавлением параметра "init=/bin/systemd". Для grub2 постоянным решением является это (требует выполнения update-grub для обновления /boot/grub/grub.cfg):

# $EDITOR /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="quiet init=/bin/systemd" <--- Измените эту строку # update-grub

Workaround #2: Установить пакет systemd-sysv и закрепить его ("hold").

Имеется проблема с "Essential flag" что необходимо обсудить с сопровождающим DebianPkg: Sysvinit .

Issue #2: Warning: "/etc/mtab is not a symlink or not pointing to /proc/self/mounts"

This issue is only a warning and can be ignored, we have it on TODO (see below "Make /etc/mtab a symlink to /proc/self/mounts. Requires a newer util-linux package which stores user options separately."). ()

The full error-message in dmesg:

[ 5.784886] systemd: /etc/mtab is not a symlink or not pointing to /proc/self/mounts. This is not supported anymore. Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.

Workaround: Create required symlink:

# ln -sf /proc/self/mounts /etc/mtab

Issue #3: Dependency cycle in portmap/nfs-common/rpcbind

The nfs-common / portmap / rpcbind SysV init scripts have a dependency cycle which will cause systemd to drop them. You will get an error message during boot like the following:

Found ordering cycle path on basic.target/start Walked on cycle path to sysinit.target/start Walked on cycle path to portmap.service/start Walked on cycle path to basic.target/start Breaking ordering cycle by deleting job portmap.service

Until the portmap / nfs-common / rpcbind init scripts have been fixed, you can get rid of those error messages by uninstalling those packages or fixing their LSB init header manually.

This problem is caused by portmap / nfs-common / rpcbind installing symlinks in both rcS and rc{2345}, see

Issue #3a: Dependency cycle breakage caused by nfs-common

A similar problem as above, but with a worse automatic resolution:

Found ordering cycle on basic.target/start Walked on cycle path to sockets.target/start Walked on cycle path to dbus.socket/start Walked on cycle path to sysinit.target/start Walked on cycle path to nfs-common.service/start Walked on cycle path to basic.target/start Breaking ordering cycle by deleting job dbus.socket/start

Corresponding bug report:

Родное монтирование

With v12 or later you can use native (means systemd"s) mount and fsck facility by making sure it is activated in /etc/systemd/system.conf.

# egrep "MountAuto|SwapAuto" /etc/systemd/system.conf Output: MountAuto=yes SwapAuto=yes

The Debian package enables native mount by default since version 15-1.

If you use Logical-Volume-Manager (LVM) make sure to upgrade your lvm2 package to the latest version available from unstable (>= 2.02.84-1) as it contains important fixes regarding the udev integration. See for more details. The 19-1 package already does this.

Отладка systemd

Sometimes it is necessary to investigate why systemd hangs on startup or on reboot/shutdown.

Solution #0: Remove "quiet" from Kernel command line (so called "cmdline" or "grub line")

Solution #1: Increase verbosity via cmdline: Add "systemd.log_target=kmsg systemd.log_level=debug"

Of course you can have a "temporary" persistent solution:

[ /etc/default/grub ] GRUB_CMDLINE_LINUX="systemd.log_target=kmsg systemd.log_level=debug" <--- Add here (by uncommenting you can easily switch to debug) # update-grub

In addition enhance cmdline with "systemd.sysv_console=1" (0: disabled, 1: enabled).

Solution #2: Increase verbosity via /etc/systemd/system.conf

LogLevel=debug <--- Uncomment this line and use "debug" (default: commented and "info") LogTarget=syslog-or-kmsg <--- Uncomment this line (default: commented) SysVConsole=yes <--- Uncomment this line (default: commented)

HINT: "man system" and "man systemd.conf" (Note: File is system.conf vs. man-page system*d*.conf)

HINT: How to check Kernel command line parameters/options?

# cat /proc/cmdline

NOTE on LogLevel (see systemd(1) and systemd.conf(5)):

"Set log level. As argument this accepts a numerical log level or the well-known syslog(3) symbolic names (lowercase): emerg, alert, crit, err, warning, notice, info, debug."

HINT: Keep a copy of /sbin/init from sysvinit package in case of rescue (so you can use init=/sbin/init.sysvinit in cmdline)!

# cp -av /sbin/init /sbin/init.sysvinit <--- Before installing systemd-sysv package

See also https://fedoraproject.org/wiki/How_to_debug_Systemd_problems

Ошибки и системы сбора ошибок

    Check upstream Bug Tracking System (short: BTS)

    Usertagged bugs in Debian BTS

  • For known bugs please see topic "Known Issues and Workarounds"

TODO

  • Update more packages to ship systemd service files.
  • Draft a packaging policy involving systemd (upgrade / install / removal).
  • Provide integration for package maintainer tools: "dh_systemd"
  • invoke-rc.d/update-rc.d/service integration.
  • Get Essential flag removed from sysvinit.
  • Sort out what to do about pam_loginuid, and integration into the Debian PAM stack

Введение

Systemd - это система инициализации (init system) и системный менеджер, который получил широкое распространение и становится новым стандартом для Linux-машин. Хотя существуют обоснованные сомнения в том, является ли systemd улучшением по сравнению с традиционными системами инициализации SysV, большинство дистрибутивов уже перешли на systemd, либо планируют это сделать.

Коротко говоря, systemd отвечает за работу с процессами: запуск, остановку, проверку статуса, перезагрузка конфигурации и другое. Т.е. это очень важный аспект ОС, который нужно понимать и уметь им пользоваться. Если вам нужно проверить статус (работает или остановлена, успешно запущена или вылетела с ошибкой) службы, добавить службу в автозагрузку или убрать из автозагрузки, проверить список служб в автозагрузке, проверить свойства загружаемой службы или увидеть причины ошибки - то вы обращаетесь к systemd.

Благодаря широкому распространению systemd среди систем Linux, знакомство с ней стоит потраченного на это время, понимание systemd сделает администрирование серверов и вашего настольного Linux значительно проще. Изучение и использование инструментов и демонов, которые охватывают systemd, поможет вам лучше оценить мощность, гибкость и возможности, которые он предоставляет, или, по крайней мере, помочь вам делать вашу работу с минимальными затыками.

В этом руководстве мы обсудим команду systemctl , которая является центральным инструментом управления для контроля системы инициализации (init). Мы рассмотрим, как управлять сервисами, проверять состояния, изменять состояния системы и работать с файлами конфигурации. Мы охватим вопросы, как управлять службами, проверять статусы, изменять состояния системы и работать с конфигурационными файлами.

Обратите внимание: несмотря на то, что systemd стала стандартной системой инициализации для многих дистрибутивов Linux, она не реализована повсеместно во всех дистрибутивах. По мере прохождения этого руководства, если ваш терминал выводит ошибку bash: systemctl не установлен, (bash: systemctl is not installed) , то вероятно, на вашем компьютере установлена другая система инициализации.

Управление службами

Основная цель init системы - это инициализировать компоненты, которые должны запускаться после загрузки ядра Linux (традиционно называемые «userland» («пользовательскими») компонентами). Система init также используется для управления службами и демонами компьютера под управлением Linux в любой момент во время работы системы. Имея это в виду, мы начнем с некоторых простых операций управления службами.

В systemd целью (объектами) большинства действий являются «юниты » (units), которые представляют собой ресурсы, которыми systemd знает как управлять. Юниты классифицируются по типу ресурса, который они представляют, и определяются файлами, известными как файлы юнитов. Тип каждого юнита может быть определён по суффиксу в конце файла.

Для задач управления службой, целевым юнитом является юнит службы, которые имеют файлы юнитов с суффиксом .service . Тем не менее, для большинства команд управления службой вы фактически можете отбросить суффикс .service , поскольку systemd достаточно умён, чтобы знать, что вы, вероятно, хотите работать с сервисом при использовании команд управления службой.

Запуск и остановка служб

Чтобы запустить службу systemd, выполнив инструкции в файле юнита, используйте команду start . Если вы работаете как пользователь без полномочий root, вам придется использовать sudo , поскольку выполняемая команда повлияет на состояние операционной системы:

Sudo systemctl start приложение.service

Как мы уже упоминали выше, systemd знает, что нужно искать файлы *.service для команд управления службами, поэтому эту команду можно без проблем ввести следующим образом:

Sudo systemctl start приложение

Хотя вы можете использовать вышеуказанный формат для обычного администрирования, для ясности в остальной части команд мы будем использовать суффикс .service , чтобы быть явным в отношении цели, над которой мы работаем.

Чтобы остановить текущую службу, используется команда stop :

Sudo systemctl stop приложение.service

Перезапуск и перезагрузка

Чтобы перезапустить запущенную службу, вы можете использовать команду restart :

Sudo systemctl restart приложение.service

Если рассматриваемое приложение может перезагрузить свои файлы конфигурации (без перезапуска), вы можете выполнить команду reload , чтобы инициировать этот процесс:

Sudo systemctl reload приложение.service

Если вы не знаете, есть ли у службы функциональность для перезагрузки конфигурации, вы можете выполнить команду reload-or-restart . Она перезагрузит конфигурацию, если приложение поддерживает это. В противном случае она перезапустит службу, чтобы была подхвачена новая конфигурация:

Sudo systemctl reload-or-restart приложение.service

Включение и отключение служб

Вышеупомянутые команды полезны для запуска или остановки команд во время текущего сеанса. Чтобы система systemd автоматически запускала службы при загрузке компьютера, вы должны включить их.

Чтобы запустить службу при загрузке, используйте команду enable :

Sudo systemctl enable приложение.service

Это создаст символическую ссылку из копии файла системной службы (обычно в /lib/systemd/system или /etc/systemd/system ) в место на диске, где systemd ищет файлы автозапуска (обычно /etc/systemd/system/некая_цель.target.wants ). Мы перейдем к тому, что такое цель (target), позже в этом руководстве).

Чтобы отключить автоматический запуск службы, вы можете набрать:

Sudo systemctl disable приложение.service

Имейте в виду, что включение службы не запускает ее в текущем сеансе. Если вы хотите запустить службу и включить ее при загрузке, вам придется выпустить команды start и enable . Чтобы одновременно добавить службу в автозагрузку и запустить её, используйте ключ --now :

Systemctl enable --now apache2.service

Приведённая команда добавить веб-сервер Apache в автозагрузку и немедленно запустит его.

Переключатель --now работает с командами enable , disable и mask , соответственно для немедленного запуска, остановки или маскировки юнита, без ожидания следующей загрузки.

Символ @ («собака») в именах служб

Некоторые имена юнитов содержат символ @ (т.е. [email protected]): это означает, что они являются экземплярами юнита-шаблона, чьё действительное имя не содержит часть, которая в условном примере обозначена как string (т.е. [email protected]). string называется идентификатором экземпляра и аналогична аргументу, который передается юниту-шаблону при вызове с помощью команды systemctl: в файле юнита он будет заменять спецификатор %i .

Для большей точности работы, перед попыткой создать экземпляр [email protected] юнита-шаблона, systemd действительно ищет юнит с точным именем файла [email protected], даже не смотря на то, что такие «конфликты» довольно редки, так как большинство файлов юнитов, содержащих знак @ , подразумевают использование шаблонов. Кроме того, если юнит-шаблон вызывается без идентификатора экземпляра, ничего не получится, так как спецификатор %i не может быть подставлен.

К примеру, в файле юнита OpenVPN:

Systemctl cat [email protected]

содержится строка:

ExecStart=/usr/bin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf

В этой строке виден спецификатор %i , при его замене получится имя файла логов и файла конфигурации.

Используя различные значения string , можно добиться настройки автозапуска OpenVPN с различными конфигурационными файлами. Например:

Systemctl enable openvpn-server@port_tcp_443

Этой командой служба OpenVPN будет добавлена в автозапуск, при этом она будет запускаться с конфигурационным файлом /etc/openvpn/server/port_tcp_443.conf . Используя такой подход, можно настроить автозапуск одной и той же службы с разными конфигурациями. Например, OpenVPN на разных портах.

Многие службы поддерживают модель шаблоны-экземпляры. К примеру, Apache2:

Systemctl enable apache2@test

Эта команда приведёт к тому, что значение переменной окружения APACHE_CONFDIR будет установлено на /etc/apache2-test .

Проверка состояния служб

Чтобы проверить статус службы в вашей системе, вы можете использовать команду status :

Systemctl status приложение.service

Это выведет состояние службы, иерархию cgroup и первые несколько строк журнала.

Например, при проверке состояния веб-сервера Apache вы можете увидеть вывод следующим образом:

● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; disabled; vendor preset: disabled) Active: active (running) since Mon 2018-04-30 08:11:26 MSK; 11s ago Process: 2650 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS) Main PID: 2661 (apache2) Tasks: 7 (limit: 4580) Memory: 31.1M CGroup: /system.slice/apache2.service ├─2661 /usr/sbin/apache2 -k start ├─2662 /usr/sbin/apache2 -k start ├─2663 /usr/sbin/apache2 -k start ├─2664 /usr/sbin/apache2 -k start ├─2665 /usr/sbin/apache2 -k start ├─2666 /usr/sbin/apache2 -k start └─2667 /usr/sbin/apache2 -k start апр 30 08:11:25 HackWare systemd: Starting The Apache HTTP Server... апр 30 08:11:26 HackWare apachectl: AH00558: apache2: Could not reliably determine the server"s fully qualified domain name, using 127.0.1.1. Set the "ServerName" directive globally to suppress this message апр 30 08:11:26 HackWare systemd: Started The Apache HTTP Server.

Это даёт вам хороший обзор текущего состояния приложения, уведомляет вас о любых проблемах и любых действиях, которые могут потребоваться.

Существуют также методы проверки конкретных состояний. Например, чтобы проверить, активен ли данный элемент (работает), вы можете использовать команду is-active :

Systemctl is-active приложение.service

Это вернет текущее состояние юнита, которое обычно является active или inactive . Код выхода будет «0», если он активен, делая результат проще для парсинга программами и скриптами.

Чтобы узнать, включён ли юнит для автозапуска, вы можете использовать команду is-enabled :

Systemctl is-enabled приложение.service

Будет выведено enabled или disabled , и снова код выхода будет установлен на «0» или «1» в зависимости от ответа на вопрос команды.

Третья проверка заключается в том, находится ли устройство в состоянии сбоя. Это указывает на то, что возникла проблема с запуском рассматриваемого юнита:

Systemctl is-failed приложение.service

Это вернёт active , если он работает правильно или failed , если произошла ошибка. Если устройство было намеренно остановлено, то может быть возвращено unknown или inactive. Состояние выхода «0» означает, что произошел сбой, а статус выхода «1» указывает на любой другой статус.

Следующая команда покажет сразу все завершившиеся неудачей юниты:

Systemctl --failed

Обзор состояния системы

Команды до сих пор были полезны для управления отдельными службами, но они не очень полезны для изучения текущего состояния системы. Существует несколько команд systemctl, которые предоставляют эту информацию.

Список текущих юнитов

Чтобы просмотреть список всех активных юнитов, о которых система знает, мы можем использовать команду list-units :

Systemctl list-units

Это покажет вам список всех юнитов, которые в настоящее время systemd имеет в статусе active . Результат будет выглядеть примерно так:

Вывод имеет следующие столбцы:

  • UNIT : Имя юнита systemd
  • LOAD : Была ли конфигурация юнита успешно спарсена (разобрана) в systemd. Конфигурации загруженных юнитов хранится в памяти.
  • ACTIVE : Результирующее состояние о том, активен ли юнит. Это обычно довольно простой способ однозначно ответить на вопрос: юнит запустился успешно или нет.
  • SUB : Это состояние более низкого уровня, которое указывает более подробную информацию об устройстве. Это часто зависит от типа устройства, состояния и фактического метода, в котором работает устройство.
  • DESCRIPTION : Короткое текстовое описание, что юнит из себя представляет/делает.

Поскольку команда list-units показывает по умолчанию только активные юниты, все вышеперечисленные записи будут отображаться как «loaded » в столбце LOAD и «active » в столбце ACTIVE . Такое отображение фактически является поведением systemctl по умолчанию при вызове без дополнительных команд, поэтому вы увидите то же самое, если вы вызываете systemctl без аргументов:

Systemctl

Мы можем сказать systemctl выводить различную информацию, используя дополнительные флаги. Например, чтобы увидеть все юниты, которые systemd загрузила (или попыталась загрузить), независимо от того, активны ли они в данный момент, вы можете использовать флаг --all , например:

Systemctl list-units --all

Это покажет любой юнит, который система загрузила или попыталась загрузить, независимо от текущего состояния в системе. После запуска некоторые юниты становятся неактивными, а некоторые юниты, которые пыталась загрузить systemd, не могли быть найдены на диске.

Вы можете использовать другие флаги для фильтрации этих результатов. Например, мы можем использовать --state= флаг для указания состояний LOAD , ACTIVE или SUB , которые мы хотим видеть. Также нужно указывать флаг --all , чтобы systemctl позволяла отображать неактивные юниты:

Systemctl list-units --all --state=inactive

Другим распространенным фильтром является фильтр --type= . Мы можем сказать systemctl отображать только те юниты, которые нас интересуют. Например, чтобы видеть только активные юниты служб, мы можем использовать:

Systemctl list-units --type=service

Systemctl --type=service

Предыдущая команда покажет только активные службы, для вывода информации о всех службах добавьте ключ --all :

Systemctl --type=service --all

Вы можете явно указать статус модулей, список которых хотите получить. Для этого используйте команду:

Systemctl list-units --type=service --state=СТАТУС

Systemctl --type=service --state=СТАТУС

В качестве СТАТУСа могут быть значения:

  • active
  • inactive
  • running
  • exited
  • dead
  • loaded
  • not-found
  • plugged
  • mounted
  • waiting
  • listening

Например, вывод служб, которые завершили свою работу:

Systemctl --type=service --state=exited

Вывод служб, которые запущены в данный момент:

Systemctl list-units --type=service --state=running

Systemctl --type=service --state=running

Вывод списка всех файлов юнитов

Команда list-units отображает только юниты, которые systemd попыталась разобрать и загрузить в память. Поскольку systemd будет читать только юниты, которые, по её мнению, нужны, список не обязательно будет включать все доступные юниты в системе. Чтобы просмотреть каждый доступный файл юнита в путях systemd, включая те, которые systemd не пыталась загрузить, вместо этого вы можете использовать команду list-unit-files :

Systemctl list-unit-files

Юниты являются представлением ресурсов, о которых знает systemd. Поскольку systemd не обязательно читает все определения юнитов в этом представлении, она показывает только информацию о самих файлах. Вывод состоит из двух столбцов: файла юнита и состояние.

Если вы хотите посмотреть только юниты, добавленные в автозагрузку, то используйте следующую конструкцию:

Systemctl list-unit-files | grep enabled

Этими состояниями обычно являются «enabled», «disabled», «static» или «masked». В этом контексте static означает, что в файле unit не содержится раздел «install», который используется для включения устройства. Таким образом, эти блоки не могут быть включены. Обычно это означает, что устройство выполняет одноразовое действие или используется только как зависимость другого устройства и не должно запускаться само по себе.

Чуть ниже мы рассмотрим, что означает «masked ».

Управление юнитами

До сих пор мы работали со службами и отображали информацию о юнитах и единичных файлах, о которых знает systemd. Однако мы можем узнать более конкретную информацию о юнитах, используя некоторые дополнительные команды.

Показ файла юнита

Чтобы отобразить файл юнита, который systemd загрузила в свою систему, вы можете использовать команду cat (она была добавлена в версии systemd 209). Например, чтобы увидеть файл юнита веб-сервера Apache, мы можем ввести:

Systemctl cat apache2.service

Будет показано что-то вроде:

Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target Type=forking Environment=APACHE_STARTED_BY_SYSTEMD=true ExecStart=/usr/sbin/apachectl start ExecStop=/usr/sbin/apachectl stop ExecReload=/usr/sbin/apachectl graceful PrivateTmp=true Restart=on-abort WantedBy=multi-user.target

Будет выведен файл юнита как он известен текущему работающему процессу systemd. Это может быть важно, если вы недавно модифицировали файлы юнитов, или если вы переопределяете некоторые параметры в фрагменте файла юнита (мы расскажем об этом позже).

Отображение зависимостей

Чтобы увидеть дерево зависимостей юнита, вы можете использовать команду list-dependencies :

Systemctl list-dependencies ssh.service

Это отобразит иерархию, сопоставляющую зависимости, с которыми необходимо иметь дело, чтобы запустить рассматриваемый юнит. Зависимости в этом контексте включают те юниты, которые требуются или ищутся юнитами, расположенными над ним.

Рекурсивные зависимости отображаются только для юнитов .target , которые указывают состояния системы. Чтобы рекурсивно перечислить все зависимости, включите флаг --all .

Чтобы показать обратные зависимости (юниты, зависящие от указанного юнита), вы можете добавить в команду флаг --reverse . Другими полезными флагами являются флаги --before и --after , которые могут использоваться для отображения юнитов, которые зависят от указанного устройства, начиная с до и после себя, соответственно.

Проверка свойств юнита

Чтобы увидеть низкоуровневые свойства юнита, вы можете использовать команду show . Она отобразит список свойств, заданных для указанного юнита, используя формат ключ=значение :

Systemctl show sshd.service

Если вы хотите отобразить одно свойство, вы можете передать с флагом -p имя свойства. Например, чтобы увидеть конфликты, которые имеет юнит ssh.socket, вы можете ввести:

Systemctl show ssh.socket -p Conflicts

Применение и снятие маски юнитов

В разделе управления службами мы рассмотрели, как остановить или отключить службу, но systemd также имеет возможность пометить устройство как полностью неспособное к запуску, автоматически или вручную, связав его с /dev/null . Это называется маскировкой юнитов и возможно с помощью команды mask :

Sudo systemctl mask nginx.service

Это предотвратит запуск службы Nginx, автоматически или вручную, до тех пор, пока она замаскирована.

Если вы проверите list-unit-files , вы увидите, что служба теперь отображается как masked (замаскированная):

Systemctl list-unit-files

Если вы попытаетесь запустить службу, вы увидите следующее сообщение:

Sudo systemctl start nginx.service Failed to start nginx.service: Unit nginx.service is masked.

Чтобы снять маску с юнита, сделав его доступным для использования снова, просто используйте команду unmask :

Sudo systemctl unmask nginx.service

Это вернет юнит в прежнее состояние, позволяя ему запускаться или включаться.

Редактирование файлов юнитов

Хотя в этом руководстве мы не будет затрагивать вопрос формата файлов юнитов, знайте, что systemctl предоставляет встроенные механизмы для редактирования и изменения файлов юнитов, если вам нужно внести коррективы. Эта функциональность была добавлена в systemd версии 218.

Команда edit по умолчанию откроет фрагмент файла юнита для данного элемента:

Sudo systemctl edit ssh.socket

Это будет пустой файл, который может использоваться для переназначения или добавления директив к определению юнита. Будет создана директория внутри директории /etc/systemd/system , которая содержит имя юнита с добавленным .d . Например, для службы ssh.socket будет создана директория /etc/systemd/system/ssh.socket.d/ .

Внутри этой директории будет создан сниппет (фрагмент) с именем override.conf . Когда загружается юнит, systemd будет в памяти объединять фрагмент переопределения с полным файлом юнита. Директивы фрагмента будут иметь приоритет над теми, что указаны в исходном файле юнита.

Если вы хотите отредактировать полный файл юнита вместо создания фрагмента, вы можете передать флаг --full :

Sudo systemctl edit --full ssh.socket

Это загрузит текущий файл юнита в редактор, где его можно будет изменить. При выходе из редактора, измененный файл будет записан в /etc/systemd/system , он будет иметь приоритет над системным определением юнита (который обычно находится где-то в /lib/systemd/system ).

Чтобы удалить все сделанные вами дополнения, удалите каталог конфигурации .d или измененный служебный файл из /etc/systemd/system . Например, чтобы удалить сниппет, мы можем ввести:

Sudo rm -r /etc/systemd/system/ssh.socket.d

Для удаления полного модифицированного файла юнита, можно было бы напечатать:

Sudo rm /etc/systemd/system/ssh.service

После удаления файла или каталога вы должны перезагрузить процесс systemd, чтобы он больше не пытался ссылаться на эти файлы и возвращался обратно к использованию системных копий. Вы можете сделать это, набрав:

Sudo systemctl daemon-reload

Настройка состояния системы (уровень запуска) с помощью целей

Целями (targets) являются специальные файлы юнитов, которые описывают состояние системы или точку синхронизации. Как и другие юниты, файлы, которые определяют цели, могут быть идентифицированы по их суффиксу, которым в этом случае является .target . Цели сами по себе много не делают, но вместо этого используются для группировки других единиц.

Это можно использовать, чтобы привести систему в определенные состояния, так же как и другие системы инициализации используют уровни запуска. Они используются в качестве справочного материала, когда доступны определенные функции, позволяя вам указать желаемое состояние вместо отдельных юнитов, необходимых для создания этого состояния.

Например, есть swap.target , который используется для указания того, что swap готов к использованию. Юниты, которые являются частью этого процесса, могут синхронизироваться с этой целью, указывая в своей конфигурации, что они WantedBy= или RequiredBy= цель swap.target . Юниты, для которых требуется файл подкачки, могут указывать это условие, используя спецификации Wants= , Requires= и After= , чтобы указать характер их отношений.

Получение и установка дефолтной цели

Процесс systemd имеет цель по умолчанию, которую он использует при загрузке системы. Удовлетворение каскада зависимостей от этой единственной цели приведет систему в желаемое состояние. Чтобы найти цель по умолчанию для вашей системы, введите:

Systemctl get-default

Пример вывода

Multi-user.target

Если вы хотите установить другую цель по умолчанию, вы можете использовать set-default . Например, если у вас установлен графический рабочий стол, и вы хотите, чтобы система загрузилась по умолчанию в графическое окружение, вы можете соответствующим образом изменить цель по умолчанию:

Sudo systemctl set-default graphical.target

Список доступных целей

Вы можете получить список доступных целей в своей системе, введя:

Systemctl list-unit-files --type=target

В отличие от уровней запуска, несколько целей могут быть активны за один раз. Активная цель указывает, что systemd попытался запустить все юниты, привязанные к цели, и не попытался снова их отключить (teardown). Чтобы увидеть все активные цели, введите:

Systemctl list-units --type=target

Изоляция целей

Можно запустить все юниты, связанные с целью, и остановить все юниты, которые не являются частью дерева зависимостей. Команда, которая нам нужна для этого, называется isolate . Это похоже на изменение уровня запуска в других системах инициализации.

Например, если вы работаете в графической среде с активным graphical.target , вы можете отключить графическую систему и перевести систему в состояние многопользовательской командной строки, изолировав multi-user.target . Поскольку graphical.target зависит от multi-user.target , но не наоборот, все графические блоки будут остановлены.

Вы можете взглянуть на зависимости цели, которую вы изолируете, прежде чем выполнять эту процедуру, чтобы убедиться, что вы не останавливаете жизненно важные службы:

Systemctl list-dependencies multi-user.target

Если вас устраивают юниты, которые будут сохранены в живых, вы можете изолировать цель, набрав:

Sudo systemctl isolate multi-user.target

Использование ярлыков для важных событий

Имеются цели, определенные для важных событий, таких как выключение или перезагрузка. Тем не менее, systemctl также имеет несколько ярлыков, которые добавляют немного дополнительной функциональности.

Например, чтобы вывести систему в режим спасения (однопользовательский), вы можете просто использовать команду rescue вместо изолирования rescue.target :

Sudo systemctl rescue

Это обеспечит дополнительную функциональность оповещения всех зарегистрированных пользователей о событии.

Чтобы остановить систему, вы можете использовать команду halt :

Sudo systemctl halt

Чтобы начать полное завершение работы, вы можете использовать команду poweroff :

Sudo systemctl poweroff

Перезапуск можно запустить с помощью команды reboot :

Sudo systemctl reboot

Все эти оповещения регистрируются пользователями, для которых происходит это событие; а то, что просто запускает или изолирует цель - нет. Обратите внимание, что большинство машин свяжут более короткие, более обычные команды для этих операций, чтобы они работали правильно с systemd.

Например, чтобы перезагрузить систему, вы обычно можете ввести:

Sudo reboot

Заключение

К настоящему времени вы должны быть знакомы с некоторыми основными возможностями команды systemctl , которые позволяют вам взаимодействовать с вашим экземпляром systemd и управлять им. Утилита systemctl будет вашей основной точкой взаимодействия со слулжбами и управлением состоянием системы.

Хотя systemctl работает в основном с процессом ядра systemd , в системе systemd есть другие компоненты, которые контролируются другими утилитами. Другие возможности, такие как управление журналом и пользовательские сеансы, обрабатываются отдельными демонами и утилитами управления (journald /journalctl и logind /loginctl соответственно). Найдите время, чтобы ознакомиться с этими другими инструментами и демонами, это сделает управление более простой задачей.



2024 stdpro.ru. Сайт о правильном строительстве.