Systemd
Последнее изменение этой страницы: 19:18, 20 декабря 2015.
- systemd - менеджер системы и служб для Linux, совместимый со скриптами инициализации SysV и LSB. systemd обеспечивает возможности агрессивной параллелизации, использует сокеты и активацию D-Bus для запускаемых служб, предлагает запуск демонов по необходимости, отслеживает процессы при помощи контрольных групп Linux, поддерживает мгновенные снимки и восстановление состояния системы, монтирование и точки монтирования, а также внедряет основанную на зависимостях логику контроля процессов сложных транзакций.
Содержание
- 1 Основы использования systemctl
- 2 Написание файлов юнитов
- 3 Цели
- 4 Журнал
- 5 Решение проблем
- 5.1 По-видимому, процессы с кратким сроком жизни не оставляют записей в логах
- 5.2 Отключение журналирования аварийных дампов памяти приложений
- 5.3 Время загрузки системы увеличивается с течением времени
- 5.4 systemd-tmpfiles-setup.service не удается запустить при загрузке
- 5.5 systemctl не удается включить символические ссылки в /etc/systemd/system
- 6 Смотрите также
Основы использования 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
Смотрите также
- Systemd для администраторов (Рус.)
- systemd для администраторов (PDF) - перевод цикла статей Леннарта Поттеринга (Lennart Poettering)
- Официальный веб-сайт (англ.)
- Статья в Википедии
- Страницы справочных руководств (англ.)
- Оптимизации systemd (англ.)
- FAQ (англ.)
- Советы и трюки (англ.)
- О systemd в Fedora Project (англ.)
- Отладка проблем systemd (англ.)
- часть 1 и часть 2 вводной статьи в журнале The H Open (англ.)
- Блог Lennart'а (англ.)
- Status update (англ.)
- Status update2 (англ.)
- Status update3 (англ.)
- Самые последние изменения (англ.)
- Шпаргалка Fedora по переходу с SysVinit на systemd
- Статья systemd в Gentoo Wiki (англ.)
ISSN 2542-0356
Следуй за Полисом
Оставайся в курсе последних событий
Лицензия
Если не указано иное, содержание этой страницы доступно по лицензии Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0, а примеры кода – по лицензии Apache 2.0. Подробнее см. Условия использования.