LINUX.ORG.RU
решено ФорумAdmin

Несколько вопросов по systemd

 


0

4

Прочитав маны по systemd и его юнитам, я, тем не менее, понял не всё, что хотел понять. Не могли бы вы прояснить несколько моментов?

1.) Что такое юнит типа scope? Какие функции он исполняет?

2.) Правильно ли я понимаю, что управление всеми точками монтирования, свап-файлами происходит силами systemd, основываясь на юнитах, сгенерированных из fstab или созданных отдельно?

3.) Как происходит монтирование корневой ФС, а так же работа с шифрованными носителями, с точки зрения systemd?

4.) Правильно ли я понимаю, что те юниты, которые имеют состояние masked, мне трогать не следует, и, если я не пишу и не меняю юниты, то меня интересуют только те, которые имеют состояние enabled/disabled?

Заранее спасибо

В таким темах надо обязательно кастовать intelfx, хотя он и сам приползает обычно.

unikum ★★★★★
()

Что такое юнит типа scope? Какие функции он исполняет?

Юниты типа scope создаются через API systemd (т. е. не заранее в /etc/systemd/system, а на лету) и используются для того, чтобы силами systemd добавить уже существующие процессы в новую контрольную группу. Например,

  • systemd-run /path/to/program запустит программу в отдельном service-юните, т. е. как потомка systemd, а
  • systemd-run --scope /path/to/program — запустит ту же программу как потомка systemd-run, но всё равно в отдельной контрольной группе (в отдельном scope-юните).

Зачем это обязательно нужно делать силами systemd (а не самостоятельно) — вот примерно поэтому.

Правильно ли я понимаю, что управление всеми точками монтирования, свап-файлами происходит силами systemd, основываясь на юнитах, сгенерированных из fstab или созданных отдельно?

Да. systemd (точнее, отдельный бинарь-генератор) при запуске и при каждом daemon-reload перечитывает fstab и создаёт во временной директории эквивалентный ему набор .mount и .swap-юнитов, между которыми уже расставляются зависимости и так далее.

Можно, например, написать systemctl stop /mnt/something (или systemctl stop mnt-something.mount). Это отмонтирует директорию /mnt/something, предварительно 1) отмонтировав всё, что под ней, 2) отмонтировав все bind-ы её частей и 3) остановив все юниты, в которых указана зависимость от этой директории.

Как происходит монтирование корневой ФС <...> с точки зрения systemd?

Оно происходит до запуска systemd.

а так же работа с шифрованными носителями

Я не пользовался dm-crypt'ом и cryptsetup, но вроде как для этого есть отдельный набор юнитов, которые запускаются до монтирования всех ФС. Результатом их работы является создание какого-то количества новых виртуальных блочных устройств. Они автоматически подцепляются systemd и уже с них монтируются файловые системы.

Правильно ли я понимаю, что те юниты, которые имеют состояние masked, мне трогать не следует, и, если я не пишу и не меняю юниты, то меня интересуют только те, которые имеют состояние enabled/disabled?

Нет. По умолчанию, без вмешательства администратора, ни один юнит не имеет состояние masked. Маскировка — это принудительный запрет любого запуска юнита; грубо говоря, замещение файла юнита пустым файлом.

И да: про операции с юнитами и прочие подробности, действительно, читай SIA #1 и SIA #2.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Да. systemd (точнее, отдельный бинарь-генератор) при запуске и при каждом daemon-reload перечитывает fstab и создаёт во временной директории эквивалентный ему набор .mount и .swap-юнитов

Если у тебя GPT, то тут выходит на сцену systemd-gpt-auto-generator и

Also, on systems where the units are explicitly configured (for example, listed in fstab(5)), the units this generator creates are overriden, but additional automatic dependencies might be created.

он играет по своим правилам.

Deleted
()
Ответ на: комментарий от intelfx

Спасибо, многое прояснилось. Осталась ещё пара вопросов - те шифрованные носители и файловые системы, которые были открыты/смонтированы до запуска systemd, тоже получают соответствующие юниты, или они остаются невидимыми для systemd? Получают ли соответствующие юниты те точки монтирования, которые были смонтированы вручную через mount?

З.Ы. У меня в Debian Stable по-умолчанию есть 32 замаскированных юнита.

Anonymous654
() автор топика
Ответ на: комментарий от Deleted

Да, верно. Только fstab оверрайдит то, что нагенерено из GPT (собственно, как и написано).

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от Anonymous654

Все смонтированные без участия systemd файловые системы тоже получают свои mount-юниты (и не только до старта, а динамически). А открытые без systemd криптоустройства — нет.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Я тут обнаружил, что нередки случаи, когда один сервис является симлинком на другой, и один включён, а другой выключен. Например, network-manager.service у меня выключен, а NetworkManager.service бодр и в автозапуске, причём первый - это симлинк на второй. Так же и с lvm2 и lvm2-activation. Нельзя ли как-нибудь сделать так, чтобы выхлоп systemctl учитывал такие странные обстоятельства и опускал лишнее?

Anonymous654
() автор топика
Ответ на: комментарий от intelfx

Читаю, читаю про Systemd - понимаю, за что его ненавидят некоторые. Сложная архитектура, да. Но функционал того стоит, я в ужасе и восторге одновременно.

Anonymous654
() автор топика
Ответ на: комментарий от Anonymous654

А, ну он так и должен работать. Параметра «скипать алиасы» там нет. Только вот у меня если юнит enabled, то ссылки на него тоже enabled. Почему у тебя по-другому, не знаю.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

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

Anonymous654
() автор топика
Ответ на: комментарий от intelfx

graphical.target:

Wants=display-manager.service
locate display-manager.service

пусто

systemctl status display-manager.service

Loaded: loaded (/lib/systemd/system/lightdm.service; static) При этом в теле юнита lightdm.service ни слова о том, что он должен прикидываться display-manager.

Как это отслеживается?

Anonymous654
() автор топика
Ответ на: комментарий от Anonymous654
$ ssh operator@intelfx.name grep -C1 display-manager.service /lib/systemd/system/lightdm.service
[Install]
Alias=display-manager.service

Ещё, может быть, в дебиане нужный симлинк поставляется с пакетом статически или создаётся каким-нибудь update-alternatives или ещё чем-нибудь дебианоспецифичным (не шарю).

В любом случае, это симлинк display-manager.service -> lightdm.service.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

О чё я нашёл:

cat ./run/systemd/generator.early/display-manager.service
[Unit]
Description=Light Display Manager
Documentation=man:lightdm(1)
After=systemd-user-sessions.service

[Service]
# temporary safety check until all DMs are converted to correct
# display-manager.service symlink handling
ExecStartPre=/bin/sh -c '[ "$(cat /etc/X11/default-display-manager 2>/dev/null)" = "/usr/sbin/lightdm" ]'
ExecStart=/usr/sbin/lightdm
Restart=always
BusName=org.freedesktop.DisplayManager

Это ещё один systemd-генератор. Ёмаё как всё запутанно.

Anonymous654
() автор топика
Ответ на: комментарий от intelfx

Ещё, может быть, в дебиане нужный симлинк поставляется с пакетом статически или создаётся каким-нибудь update-alternatives или ещё чем-нибудь дебианоспецифичным (не шарю).

Не знаю, как в арче и дебиане, а в федоре симлинк создается в install-скрипте lightdm (см. https://fedoraproject.org/wiki/Features/DisplayManagerRework):

postinstall scriptlet (using /bin/sh):

if [ $1 -eq 1 ] ; then 
        # Initial installation 
        systemctl preset lightdm.service >/dev/null 2>&1 || : 
fi
Причем в пакете systemd есть, кроме прочего, файл /usr/lib/systemd/system-preset/85-display-manager.preset, а в нем
# We enable all display managers by default. Since only one can
# actually be enabled at the same time the one which is installed
# first wins

enable gdm.service
enable lightdm.service
enable slim.service
enable lxdm.service
enable sddm.service
enable kdm.service
enable xdm.service

dexpl ★★★★★
()
Ответ на: комментарий от intelfx

Я сделал systemctl preset-all, многое изменилось. Большую часть изменений я осознал, но остались вопросы.

Если у меня есть .service и .socket одной сущности, то только один должен быть активен одновременно?

console-getty.service
console-shell.service
autovt@.service
getty@.service
serial-getty@.service

Вот у меня есть пять юнитов, каждый из которых при установке пропишется в зависимости getty.target. Про console-shell я понял, что он, видимо, логинит единственно рута (для режима восстановления, видимо):

Environment=HOME=/root
WorkingDirectory=/root
ExecStart=-/sbin/sulogin
ExecStopPost=-/bin/systemctl poweroff
getty@ у меня используется по умолчанию, про autovt я тоже всё понял, а вот разница между getty@, console-getty и serial-getty мною не вылавливается:

/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM
/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM

Нет ли у тебя соображений на этот счёт?

Anonymous654
() автор топика
Ответ на: комментарий от Anonymous654

Если у меня есть .service и .socket одной сущности, то только один должен быть активен одновременно?

Тут всё очень интересно. Видишь ли, есть два типа сокет-активации. Первая — когда в .socket-юните есть директива Accept=true. В этом случае на каждое подключение к сокету запускается отдельная копия основной программы (с помощью шаблонного .service-юнита, в instance к которому прописывается просто рандомная строка). В этом случае ты включаешь и запускаешь только .socket-юнит (у которого есть [[Install]]-секция), а инстансы программы запускаются по необходимости.

Если у этой же программы есть ещё и обычный, не-шаблонный, .service-юнит, то он обычно реализует ту же самую логику, но силами самой программы (легаси-режим). Поэтому в таких случаях нужно включать/запускать ИЛИ .socket, ИЛИ .service, но не оба, т. к. они, грубо говоря, будут драться за один и тот же порт.

Так, например, сделано в smbd или sshd:

$ systemctl list-unit-files sshd* smbd* | grep -v sshdgenkeys
UNIT FILE           STATE   
smbd.service        disabled
smbd@.service       static  
sshd.service        disabled
sshd@.service       static  
smbd.socket         enabled 
sshd.socket         enabled

И есть второй вид сокет-активации, когда все подключения обрабатываются одной и той же копией программы, а сокет-активация используется лишь для того, чтобы не расставлять лишние зависимости или просто не запускать программу до первого соединения (подробнее об этом у Леннарта).

В этом случае есть только два юнита (.socket и одноимённый не-шаблонный .service), и они могут быть включены/запущены одновременно. Более того, часто делают так, что при попытке включения .service-юнита автоматически включается .socket-юнит:

$ systemctl --user cat pulseaudio.service | fgrep -A10 '[Install]'
[Install]
Also=pulseaudio.socket
WantedBy=default.target

Собственно, так сделано в pulsaudio, udevd и ещё куче мелких демонов в составе systemd.

Так, например, работает

intelfx ★★★★★
()
Ответ на: комментарий от Anonymous654

Эти дебиановцы реально больные какие-то.

Deleted
()
Ответ на: комментарий от Anonymous654

Вот у меня есть пять юнитов, каждый из которых при установке пропишется в зависимости getty.target.
console-getty.service
console-shell.service
autovt@.service
getty@.service
serial-getty@.service

Ни один из этих юнитов обычно не нужно включать или запускать руками.

Во-первых, есть такая штука, как systemd-getty-generator. Опять же, подробнее у Леннарта. Попытаюсь вкратце пересказать суть.

console-getty.service — это запуск getty на устройстве /dev/console. Этот юнит включается вышеупомянутым генератором, если система запущена в контейнере (в контейнерах обычно нет никаких TTY/VT, кроме /dev/console).

console-shell.service — отладочный юнит. Его никто автоматически не запускает.

autovt@ttyN.service — эти юниты в рантайме запускаются logind, когда кто-то в первый раз переключается на виртуальный терминал N. Это сделано для того, чтобы не запускать всегда шесть getty, даже если никто консолями не пользуется.

Этот юнит является симлинком на getty@.service (своего рода абстракция на случай, если ты вдруг захочешь замаскировать конкретные autovt@ или перенаправить его на свой собственный юнит).

getty@.service — эти юниты можно включить руками, если ты хочешь запускать getty на каких-то консолях всегда.

Наконец, serial-getty@.service — как getty@.service, только немного другой (для запуска на реальных последовательных терминалах). Дело в том, что виртуальные терминалы (Ctrl+Alt+Fx) и реальные последовательные линии нужно инициализировать немного по-разному.

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

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Оффтоп

если система запущена в контейнере

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

redgremlin ★★★★★
()
Ответ на: комментарий от intelfx

Мне не совсем ясен второй случай.

сокет-активация используется лишь для того, чтобы не расставлять лишние зависимости

Совсем-совсем не понял.

Anonymous654
() автор топика
Ответ на: комментарий от Anonymous654

Ну я же дал линк.

Предположим, программа A (клиент) коммуницирует с программой B (сервер) через сокет, причём обе программы должны автозапускаться.

Традиционный способ состоит в том, чтобы расставлять зависимости упорядочивания (запускать A только после запуска B). А если B ещё и плохо написана и не сразу становится готова принимать соединения (т. е. если есть промежуток времени между оповещением «я запустилась» и открытием сокета), всё становится вообще весело.

systemd-способ состоит в том, что мы просим systemd заблаговременно открыть сокет (это быстрая операция) и не расставляем никаких зависимостей, а программа B после завершения своей инициализации «забирает» свой сокет у systemd и начинает обрабатывать соединения. А если так получится, что программа A попытается написать что-нибудь в сокет раньше окончания запуска программы B, то ядро попросту запишет данные в буфер и заблокирует процесс A до окончания обработки.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

И ещё вопросец - правильно ли я понимаю, что все «изменения» в настройке systemd относительно дефолта «хранятся» в «/etc/systemd/», и всё, что не там - то дефолт?

Anonymous654
() автор топика
Ответ на: комментарий от Anonymous654

Почти. Есть ещё /run/systemd — это «короткоживущие» изменения, которые исчезают при перезагрузке. (Потому что /run — это tmpfs).

Приоритеты таковы: /etc/systemd > /run/systemd > /usr/lib/systemd.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Спасибо, воспринял. И, наверное, последний вопрос. В стандартной установке Debian в /etc/systemd/system находятся юниты sshd.service; syslog.service; dbus-org.freedesktop.nm-dispatcher.service, которые являются симлинками на /lib/systemd/system/ssh.service; /lib/systemd/system/rsyslog.service; /lib/systemd/system/NetworkManager-dispatcher.service соответственно. Правильно ли я понимаю, что это сделано для совместимости, и мне следует сделать «enabled» те юниты, которые лежат в /etc/systemd/system, а те, на которые они указывают, сделать «disabled»?

Anonymous654
() автор топика
Ответ на: комментарий от intelfx

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

Но в /lib/systemd/system у меня ещё есть lvm2.service - симлинк на lvm2-activation.service и network-manager.service - симлинк на NetworkManager.service, алиасы не прописаны. Как думаешь, нахрена это?

Anonymous5237
()
9 ноября 2015 г.
Ответ на: комментарий от Chaser_Andrey

О, не заметил. Пнул бы меня седьмого числа, на хакфесте. А сейчас вспомнил, да. Как только руки дойдут до systemd — запилю...

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.