Systemd

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 19:18, 20 декабря 2015.
systemd - менеджер системы и служб для Linux, совместимый со скриптами инициализации SysV и LSB. systemd обеспечивает возможности агрессивной параллелизации, использует сокеты и активацию D-Bus для запускаемых служб, предлагает запуск демонов по необходимости, отслеживает процессы при помощи контрольных групп Linux, поддерживает мгновенные снимки и восстановление состояния системы, монтирование и точки монтирования, а также внедряет основанную на зависимостях логику контроля процессов сложных транзакций.

Содержание

Основы использования systemctl

Главная команда для отслеживания и контроля состояния systemd - команда systemctl. Некоторые из вариантов ее использования связаны с изучением состояния системы и управлением системой и службами.

Анализ состояния системы

Список запущенных юнитов:

$ systemctl

или:

$ systemctl list-units

Список неудач, - список юнитов, попытка запуска которых не удалась:

$ systemctl --failed

Доступные файлы юнитов можно посмотреть в директориях /usr/lib/systemd/system/ и /etc/systemd/system/ (второй каталог имеет приоритет). Вы можете увидеть список установленных файлов юнитов командой:

$ systemctl list-unit-files

Использование юнитов

Юнитами могут быть, например, службы (.service), точки монтирования (.mount), устройства (.device) или сокеты (.socket).

При использовании systemctl обычно всегда необходимо указывать полное имя файла юнита, включая суффикс, например, sshd.socket. Однако, есть несколько сокращений для указания юнита в следующих командах systemctl:

  • Ели вы не указали суффикс, systemctl предполагает, что это .service. Например, netctl и netctl.service будут трактоваться одинаково
  • Точки монтирования будут автоматически преобразованы в соответствующий юнит .mount. Например, указание /home равнозначно home.mount
  • Так же, как и точки монтирования, имена устройств автоматически преобразуются в соответствующий юнит .device, поэтому указание /dev/sda2 полностью соответствует юниту dev-sda2.device

Незамедлительно запустить юнит:

# systemctl start юнит

Незамедлительно остановить юнит:

# systemctl stop юнит

Перезапустить юнит:

# systemctl restart юнит

Запросить у юнита перезагрузку его настроек:

# systemctl reload юнит

Показать статус юнита, а также запущен он или нет:

$ systemctl status юнит

Проверить, включен ли юнит в автозапуск при загрузке системы:

$ systemctl is-enabled юнит

Включить юнит в автозапуск при загрузке системы:

# systemctl enable юнит

Убрать юнит из автозапуска при загрузке системы:

# systemctl disable юнит

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

# systemctl mask юнит 

Снять маску юнита:

# systemctl unmask юнит 

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

$ systemctl help юнит

Перезагрузить systemd для поиска новых или измененных юнитов:

# systemctl daemon-reload

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

Для управления питанием от имени непривилегированного пользователя необходим polkit. Если вы находитесь в локальной пользовательской сессии systemd-logind, и нет других активных сессий, приведенные ниже команды сработают и без привилегий суперпользователя. В противном случае (например, вследствие того, что другой пользователь вошел в систему в tty), systemd автоматически запросит у вас пароль суперпользователя.

Завершить работу и перезагрузить систему:

$ systemctl reboot

Завершить работу и выключить компьютер (с отключением питания):

$ systemctl poweroff

Перевести систему в ждущий режим:

$ systemctl suspend

Перевести систему в спящий режим:

$ systemctl hibernate

Перевести систему в режим гибридного сна (или suspend-to-both):

$ systemctl hybrid-sleep

Написание файлов юнитов

Синтаксис файлов юнитов systemd вдохновлен файлами .desktop XDG Desktop Entry Specification, а они, в свою очередь - файлами .ini Microsoft Windows. Файлы юнитов загружаются из двух мест. Вот они по приоритету от низшего к высшему:

  • /usr/lib/systemd/system/: юниты, предоставляемые пакетами при их установке
  • /etc/systemd/system/: юниты, устанавливаемые системным администратором

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

В случае использования systemd зависимости могут быть указаны правильным построением файлов юнитов. Наиболее частый случай -- юниту A требуется, чтобы юнит B был запущен перед тем, как запустится сам юнит A. В этом случае добавьте строки Requires=B и After=B в секцию [Unit] файла службы A. Если подобная зависимость не является обязательной, взамен указанных выше добавьте, соответственно, строки Wants=B и After=B. Обратите внимание, что Wants= и Requires= не подразумевают After=, что означает, что если After= не определено, два юнита будут запущены параллельно друг другу.

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

Типы служб

Существует несколько различных типов запуска служб, которые надо иметь в виду при написании пользовательского файла службы. Тип определяется параметром Type= в секции [Service]:

  • Type=simple (по умолчанию): systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы. Исключение - активация сокета
  • Type=forking: systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. Используйте данный тип для запуска классических демонов за исключением тех случаев, когда, как вам известно, в таком поведении процесса нет необходимости. Вам следует также определить PIDFile=, чтобы systemd могла отслеживать основной процесс
  • Type=oneshot: полезен для скриптов, которые выполняют одно задание и завершаются. Вам может понадобиться также установить параметр RemainAfterExit=yes, чтобы systemd по-прежнему считала процесс активным, даже после его завершения
  • Type=notify: идентичен параметру Type=simple, но с той оговоркой, что демон пошлет systemd сигнал о своей готовности. Эталонная реализация данного уведомления представлена в libsystemd-daemon.so
  • Type=dbus: сервис считается находящимся в состоянии готовности, когда определенное BusName появляется в системной шине DBus
  • Type=idle: systemd задержит выполнение двоичного файла службы до тех пор, пока все задания отправляются. Кроме того, поведение очень похоже на Type=simple.

Смотрите справочную страницу руководства systemd.service(5) для более детального пояснения значений Type.

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

Есть два способа редактирования файлов юнита, предоставленного пакетом: заменить весь блок файла на новый или создать фрагмент кода, который применяется в верхней части существующего блока файла. В обоих методах, чтобы применить изменения, нужно перезагрузить юнит. Это может быть сделано либо путем редактирования блока с помощью Шаблон:Ic (которая автоматически загружает модуль) либо при перезагрузке всех юнитов:

# systemctl daemon-reload

Замена файлов юнита

Чтобы заменить файл юнита /usr/lib/systemd/system/юнит, создайте файл /etc/systemd/system/юнит и перезапустите юнит для обновления символьных ссылок:

# systemctl reenable юнит

В качестве альтернативы, можно выполнить:

# systemctl edit --full юнит

Эта команда откроет /etc/systemd/system/юнит в вашем текстовом редакторе (копирует установленную версию, если она еще не существует) и автоматически загружает её, когда вы закончите редактирование.

Drop-in snippets

Чтобы создать drop-in snippets для файла юнита /usr/lib/systemd/system/юнит, создайте каталог /etc/systemd/system/юнит.d/ и поместите файлы .conf там, чтобы отменять или добавлять новые опции. systemd будет анализировать эти файлы .conf и применять их поверх оригинального юнита.

Самый простой способ чтобы выполнить это, сделайте:

# systemctl edit юнит

Эта команда откроет /etc/systemd/system/юнит.d/override.conf (создаст его если это потребуется) в вашем текстовом редакторе и автоматически перезапустит юнит, когда вы закончите редактирование.

Цели

systemd использует цели (англ. target), которые выполняют ту же задачу, что и уровни запуска (англ. runlevel), но действуют немного по-другому. Каждая цель поименована (т.е. имеет собственное имя, а не номер) и, как предполагается, предназначена для конкретных задач; возможно иметь в одно и то же время активными несколько таких целей. Некоторые цели реализованы так, что наследуют все службы других целей, добавляя к ним свои. В systemd имеются также цели, которые имитируют общие уровни запуска SystemVinit, поэтому вы можете переключаться между целевыми юнитами, используя привычную команду telinit RUNLEVEL.

Получение информации о текущих целях

При использовании systemd для этого предназначена следующая команда (заменяющая runleve):

$ systemctl list-units --type=target

Создание пользовательской цели

Уровни запуска, по которым расписаны конкретные задачи при установке ванильной Fedora по умолчанию - 0, 1, 3, 5 и 6 - имеют соответствие 1:1 с конкретными целями systemd. К сожалению, не существует хорошего способа сделать то же самое для определяемых пользователем уровней, таких как 2 и 4. Их использование предполагает, что вы создаете новый именованный целевой юнит systemd наподобие /etc/systemd/system/ваша цель, который берет за основу один из существующих уровней запуска (взгляните, например, на /usr/lib/systemd/system/graphical.target), создаете каталог /etc/systemd/system/ваша цель.wants, а после этого - символические ссылки на дополнительные службы из директории /usr/lib/systemd/system/, которые вы хотите включить при загрузке.

Таблица целей

Уровнень запуска SysV Цель systemd Примечания
0 runlevel0.target, poweroff.target Выключить систему
1, s, single runlevel1.target, rescue.target Однопользовательский уровень запуска
2, 4 runlevel2.target, runlevel4.target, multi-user.target Уровни запуска, определенные пользователем/специфичные для узла. По умолчанию соответствует уровню запуска 3
3 runlevel3.target, multi-user.target Многопользовательский режим без графики. Пользователи, как правило, входят в систему при помощи множества консолей или через сеть
5 runlevel5.target, graphical.target Многопользовательский режим с графикой. Обычно эквивалентен запуску всех служб на уровне 3 и графического менеджера входа в систему
6 runlevel6.target, reboot.target Перезагрузка
emergency emergency.target Аварийная оболочка

Изменение текущей цели

В systemd цели доступны посредством целевых юнитов. Вы можете изменить их командой:

# systemctl isolate graphical.target

Данная команда изменит только лишь текущую цель и не повлияет на следующую загрузку системы. Она соответствует командам Sysvinit вида telinit 3 и telinit 5.

Изменение цели загрузки по умолчанию

Стандартная цель - default.target, которая по умолчанию является псевдонимом graphical.target (примерно соответствующего прежнему уровню запуска 5). Для изменения цели загрузки по умолчанию добавьте один из следующих параметров ядра в ваш загрузчик:

  • systemd.unit=multi-user.target (что примерно соответствует прежнему уровню запуска 3)
  • systemd.unit=rescue.target (что примерно соответствует прежнему уровню запуска 1)

Другой способ - оставить загрузчик без изменений, а изменить целевой юнит по умолчанию - default.target. Это делается с использованием systemctl:

# systemctl set-default multi-user.target

Чтобы иметь возможность перезаписать ранее установленную default.target, используйте опцию force:

# systemctl set-default -f multi-user.target

Эффект от применения данной команды выводится через systemctl. Символическая ссылка на новый целевой юнит по умолчанию создается в директории /etc/systemd/system/default.target.

Журнал

systemd имеет собственную систему ведения логов, названную журналом (journal). В связи с этим больше не требуется запускать демон syslog. Для чтения логов используйте команду:

# journalctl

В Arch Linux каталог /var/log/journal/ является частью пакета systemd, и по умолчанию (когда в конфигурационном файле /etc/systemd/journald.conf параметр Storage имеет значение auto журнал записывается именно в /var/log/journal/. Если вы или какая-то программа удалит этот каталог, systemd не пересоздаст его автоматически и вместо этого будет писать свои журналы по непостоянному пути /run/systemd/journal. Однако, папка будет пересоздана, когда вы установите Storage=persistent и выполните systemctl restart systemd-journald (или перезагрузитесь).

Фильтрация вывода

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

$ strings /mnt/arch/var/log/journal/af4967d77fba44c6b093d0e9862f6ddd/system.journal | grep -i сообщение

Примеры:

  • Показать все сообщения с момента текущей загрузки системы:
# journalctl -b

Однако, пользователи часто интересуются сообщениями не для текущей, а для предыдущей загрузки (например, если произошел невосстановимый сбой системы). Это возможно, если задать параметр флагу -b: journalctl -b -0 покажет сообщения с момента текущей загрузки, journalctl -b -1 - предыдущей загрузки, journalctl -b -2 - следующей за предыдущей, и т.д. Для просмотра полного описания смотрите страницу справочного руководства man 1 journalctl: имеется гораздо более мощная семантика.

  • Показать все сообщения, начиная с какой-либо даты (и, если хотите, времени):
# journalctl --since="2012-10-30 18:17:16"
  • Показать все сообщения за последние 20 минут:
# journalctl --since "20 min ago"
  • Показывать новые сообщения:
# journalctl -f
  • Показать все сообщения для конкретного исполняемого файла:
# journalctl /usr/lib/systemd/systemd
  • Показать все сообщения для конкретного процесса:
# journalctl _PID=1
  • Показать все сообщения для конкретного юнита:
# journalctl -u netcfg
  • Показать кольцевой буфер ядра:
# journalctl -k
  • Показать auth.log эквивалентно фильтрации syslog facility:
# journalctl -f -l SYSLOG_FACILITY=10

Для получения дополнительной информации смотрите страницы справочного руководства man 1 journalctl и man 7 systemd.journal-fields или пост в блоге Lennart'а.

Ограничение размера журнала

Если журнал сохраняется при перезагрузке, его размер по умолчанию ограничен значением в 10% от объема соответствующей файловой системы. Например, для директории /var/log/journal, расположенной на корневом разделе в 50 Гбайт, максимальный размер журналируемых данных составит 5 Гбайт. Максимальный объем постоянного журнала можно контролировать при помощи значения SystemMaxUse в конфигурационном файле /etc/systemd/journald.conf, поэтому для ограничения его объемом, например, в 50 Mбайт раскомментируйте и отредактируйте соответствующую строку:

/etc/systemd/journald.conf
SystemMaxUse=50M

Для получения дополнительной информации обратитесь к странице справочного руководства man journald.conf.

Очистка файлов журнала вручную

Файлы журнала находятся в /var/log/journal, так что rm будет работать. Или используйте journalctl,

Примеры:

  • Удалить файлы архива журнала занимающие на диске больше 100Мб:
# journalctl --vacuum-size=100M
  • Оставить все файлы журнала содержащие данные не старше 2-ух недель.
# journalctl --vacuum-time=2weeks

Для получения дополнительной информации, обратитесь к man journalctl.

Перенаправить журнал на /dev/tty12

Создайте drop-in каталог /etc/systemd/journald.conf.d и создайте файл fw-tty12.conf с содержимым:

/etc/systemd/journald.conf.d/fw-tty12.conf

[Journal] ForwardToConsole=yes TTYPath=/dev/tty12 MaxLevelConsole=info

Затем перезапустите systemd-journald.

Команда просмотра другого журнала

Если появилась необходимость проверить логи другой системы, которая неисправна, загрузитесь с работоспособной системы, чтобы восстановить неисправную систему. Примонтируйте диск неисправной системы, например в /mnt и укажите путь журнала через -D/--directory, например так:

$ journalctl -D /mnt/var/log/journal -xe

Решение проблем

По-видимому, процессы с кратким сроком жизни не оставляют записей в логах

Если команда journalctl -u foounit не показывает вывода для службы с коротким сроком жизни, вместо нее обратитесь к PID. Например, если загрузка службы systemd-modules-load.service завершилась неудачно и команда systemctl status systemd-modules-load показывает, что она была запущена с PID 123, то вы сможете посмотреть вывод процесса в журнале под данным PID, то есть командой journalctl -b _PID=123. Такие поля метаданных для журнала, как _SYSTEMD_UNIT и _COMM, собираются асинхронно и зависят от директории /proc в случае с действующими процессами. Исправление этой ситуации требует внесения исправлений в ядро для обеспечения предоставления этих данных через сокет, наподобие SCM_CREDENTIALS.

Отключение журналирования аварийных дампов памяти приложений

Добавьте в файл /etc/systemd/coredump.conf такую строку:

Storage=none

и выполните:

# systemctl daemon-reload 

чтобы перезагрузить конфигурацию.

Время загрузки системы увеличивается с течением времени

После использования systemd-analyze некоторое количество пользователей заметило, что их время загрузки значительно увеличилось по сравнению с тем, к чему они привыкли. После использования systemd-analyze blame NetworkManager тратил необычно большое количество времени на запуск.

Проблема некоторых пользователей была связана с тем, что /var/log/journal становился слишком большим. При этом также может уменьшаться скорость работы других команд, например, systemctl status или journalctl. Для решения проблемы можно удалить все файлы из каталога журнала (в идеале - сделав где-нибудь резервные копии, хотя бы временно) и затем установить предел размера файла журнала, как описано в разделе Ограничение размера журнала.

systemd-tmpfiles-setup.service не удается запустить при загрузке

Начиная с версии Systemd 219, /usr/lib/tmpfiles.d/systemd.conf определяет атрибуты для каталогов ACL, в /var/log/journal и, следовательно, требует чтобы поддержка ACL была включена для файловой системы, где находится журнал.

systemctl не удается включить символические ссылки в /etc/systemd/system

Если в /etc/systemd/system/foo.service symlink и systemctl enable foo.service включены, они не будут выполнены и будет показана вот такая ошибка:

Failed to issue method call: No such file or directory

Вот здесь решена данная проблема systemd. Вот что нужно сделать:

# systemctl enable /absolute/path/foo.service

Смотрите также