Управление службами Systemd. Часть 2 из 3
Управление юнитами
Теперь мы знаем, как работать с сервисами и отображать информацию о юнитах и юнит-файлах, о которых знает Systemd. Получить более конкретную информацию о юнитах можно с помощью некоторых дополнительных команд.
Просмотр юнит-файла
Чтобы отобразить юнит-файл, который загрузила Systemd, можно использовать команду cat
:
$ systemctl cat nginx.service
# /lib/systemd/system/nginx.service # Stop dance for nginx # ======================= # # ExecStop sends SIGSTOP (graceful stop) to the nginx process. # If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control # and sends SIGTERM (fast shutdown) to the main process. # After another 5s (TimeoutStopSec=5), and if nginx is alive, systemd sends # SIGKILL to all the remaining processes in the process group (KillMode=mixed). # # nginx signals reference doc: # http://nginx.org/en/docs/control.html # [Unit] Description=A high performance web server and a reverse proxy server Documentation=man:nginx(8) After=network.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed
Мы видим юнит-файл, который известен текущему запущенному процессу Systemd. Это может быть важно, если был создан файл override.conf
или файл nginx.service
(см. ниже).
Отображение зависимостей
Для просмотра дерева зависимостей юнита предназначена команда list-dependencies
:
$ systemctl list-dependencies nginx.service nginx.service ● ├─system.slice ● └─sysinit.target ● ├─apparmor.service ● ├─dev-hugepages.mount ● ├─dev-mqueue.mount ● ├─keyboard-setup.service ● ├─kmod-static-nodes.service ● ├─plymouth-read-write.service ● ├─plymouth-start.service ● ├─proc-sys-fs-binfmt_misc.automount ● ├─setvtrgb.service ● ├─sys-fs-fuse-connections.mount ● ├─sys-kernel-config.mount ● ├─sys-kernel-debug.mount ● ├─systemd-ask-password-console.path ● ├─systemd-binfmt.service ● ├─systemd-hwdb-update.service ● ├─systemd-journal-flush.service ● ├─systemd-journald.service ● ├─systemd-machine-id-commit.service ● ├─systemd-modules-load.service ● ├─systemd-random-seed.service ● ├─systemd-sysctl.service ● ├─systemd-timesyncd.service ● ├─systemd-tmpfiles-setup-dev.service ● ├─systemd-tmpfiles-setup.service ● ├─systemd-udev-trigger.service ● ├─systemd-udevd.service ● ├─systemd-update-utmp.service ● ├─cryptsetup.target ● ├─local-fs.target ● │ ├─-.mount ● │ ├─systemd-fsck-root.service ● │ └─systemd-remount-fs.service ● └─swap.target ● └─swapfile.swap
Она отобразит иерархию зависимостей, с которыми системе необходимо иметь дело, чтобы запустить этот юнит. Зависимости — это те юниты, которые требуются для работы других юнитов, которые находятся выше в иерархии.
Рекурсивные зависимости отображаются только для юнитов .target
, которые указывают состояния системы. Чтобы рекурсивно перечислить все зависимости, нужно добавить флаг all
:
$ systemctl list-dependencies nginx.service --all nginx.service ● ├─system.slice ● │ └─-.slice ● └─sysinit.target ● ├─apparmor.service ● │ └─system.slice ● │ └─-.slice ● ├─dev-hugepages.mount ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─dev-mqueue.mount ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─keyboard-setup.service ● │ ├─system.slice ● │ │ └─-.slice ● │ └─local-fs-pre.target ● ├─kmod-static-nodes.service ● │ └─system.slice ● │ └─-.slice ● ├─plymouth-read-write.service ● │ └─system.slice ● │ └─-.slice ● ├─plymouth-start.service ● │ ├─system.slice ● │ │ └─-.slice ● │ └─systemd-ask-password-plymouth.path ● │ └─-.mount ● │ └─system.slice ● │ └─-.slice ● ├─proc-sys-fs-binfmt_misc.automount ● │ └─-.mount ● │ └─system.slice ● │ └─-.slice ● ├─setvtrgb.service ● │ └─system.slice ● │ └─-.slice ● ├─sys-fs-fuse-connections.mount ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─sys-kernel-config.mount ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─sys-kernel-debug.mount ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─systemd-ask-password-console.path ● │ └─-.mount ● │ └─system.slice ● │ └─-.slice ● ├─systemd-binfmt.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-hwdb-update.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-journal-flush.service ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ ├─system.slice ● │ │ └─-.slice ● │ └─systemd-journald.service ● │ ├─system.slice ● │ │ └─-.slice ● │ ├─systemd-journald-audit.socket ● │ │ └─system.slice ● │ │ └─-.slice ● │ ├─systemd-journald-dev-log.socket ● │ │ ├─-.mount ● │ │ │ └─system.slice ● │ │ │ └─-.slice ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─systemd-journald.socket ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─systemd-journald.service ● │ ├─system.slice ● │ │ └─-.slice ● │ ├─systemd-journald-audit.socket ● │ │ └─system.slice ● │ │ └─-.slice ● │ ├─systemd-journald-dev-log.socket ● │ │ ├─-.mount ● │ │ │ └─system.slice ● │ │ │ └─-.slice ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─systemd-journald.socket ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─systemd-machine-id-commit.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-modules-load.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-random-seed.service ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─systemd-sysctl.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-timesyncd.service ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ ├─system.slice ● │ │ └─-.slice ● │ └─time-sync.target ● ├─systemd-tmpfiles-setup-dev.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-tmpfiles-setup.service ● │ └─system.slice ● │ └─-.slice ● ├─systemd-udev-trigger.service ● │ ├─system.slice ● │ │ └─-.slice ● │ └─systemd-udevd.service ● │ ├─system.slice ● │ │ └─-.slice ● │ ├─systemd-udevd-control.socket ● │ │ ├─-.mount ● │ │ │ └─system.slice ● │ │ │ └─-.slice ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─systemd-udevd-kernel.socket ● │ └─system.slice ● │ └─-.slice ● ├─systemd-udevd.service ● │ ├─system.slice ● │ │ └─-.slice ● │ ├─systemd-udevd-control.socket ● │ │ ├─-.mount ● │ │ │ └─system.slice ● │ │ │ └─-.slice ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─systemd-udevd-kernel.socket ● │ └─system.slice ● │ └─-.slice ● ├─systemd-update-utmp.service ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─system.slice ● │ └─-.slice ● ├─cryptsetup.target ● ├─local-fs.target ● │ ├─-.mount ● │ │ └─system.slice ● │ │ └─-.slice ● │ ├─systemd-fsck-root.service ● │ │ ├─system.slice ● │ │ │ └─-.slice ● │ │ └─systemd-fsckd.socket ● │ │ ├─-.mount ● │ │ │ └─system.slice ● │ │ │ └─-.slice ● │ │ └─system.slice ● │ │ └─-.slice ● │ └─systemd-remount-fs.service ● │ ├─system.slice ● │ │ └─-.slice ● │ └─local-fs-pre.target ● └─swap.target ● └─swapfile.swap ● ├─-.mount ● │ └─system.slice ● │ └─-.slice ● └─system.slice ● └─-.slice
Чтобы показать обратные зависимости (юниты, зависящие от указанного элемента), нужно добавить в команду флаг reverse
:
$ systemctl list-dependencies nginx.service --reverse nginx.service ● └─multi-user.target ● └─graphical.target
Также полезными являются флаги before
и after
— они отображают юниты, которые зависят от указанного юнита и запускаются до или после него.
$ systemctl list-dependencies nginx.service --before nginx.service ● ├─multi-user.target ● │ ├─systemd-update-utmp-runlevel.service ● │ ├─graphical.target ● │ │ ├─systemd-update-utmp-runlevel.service ● │ │ ├─ureadahead-stop.service ● │ │ ├─ureadahead-stop.timer ● │ │ └─shutdown.target ● │ └─shutdown.target ● └─shutdown.target
Проверка свойств юнита
Чтобы увидеть низкоуровневые свойства юнита, можно использовать команду show
:
$ systemctl show nginx.service Type=forking Restart=no PIDFile=/run/nginx.pid NotifyAccess=none RestartUSec=100ms .......... StartLimitAction=none FailureAction=none SuccessAction=none InvocationID=0039b12a32bb4d7d8174ebf79a832f65 CollectMode=inactive
Чтобы отобразить только одно свойство:
$ systemctl show nginx.service -p Conflicts Conflicts=shutdown.target
Маскировка юнитов
Systemd может блокировать юнит (автоматически или вручную), создавая симлинк на /dev/null
. Это называется маскировкой юнитов и выполняется командой mask
:
$ sudo systemctl mask nginx.service Created symlink /etc/systemd/system/nginx.service → /dev/null.
Теперь сервис Nginx не будет запускаться автоматически или вручную до тех пор, пока включена маскировка.
$ systemctl list-unit-files UNIT FILE STATE ------------------------------------------------- proc-sys-fs-binfmt_misc.automount static .................... nginx.service masked .................... ureadahead-stop.timer static 337 unit files listed.
$ sudo systemctl start nginx.service Failed to start nginx.service: Unit nginx.service is masked.
Чтобы разблокировать юнит и сделать его доступным:
$ sudo systemctl unmask nginx.service
Редактирование юнит-файлов
Команда edit
создает в каталоге /etc/systemd/system
новый каталог nginx.service.d
, помещает в него пустой файл override.conf
и открывает этот файл на редактирование:
$ sudo systemctl edit nginx.service
[Unit] Description=Высокопроизводительный веб-сервер и обратный прокси-сервер
Этот файл можно использовать для переопределения или добавления директив в определение юнита. Когда юнит загружается, Systemd объединит в памяти файл override.conf
с остальным юнит-файлом. Директивы override.conf
будут иметь приоритет над теми, что указаны в исходном юнит-файле.
Проверим, что описание Nginx теперь на русском языке:
$ sudo systemctl restart nginx
$ systemctl status nginx ● nginx.service - Высокопроизводительный веб-сервер и обратный прокси-сервер Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/nginx.service.d └─override.conf Active: active (running) since Mon 2020-01-06 13:54:14 EET; 24min ago Docs: man:nginx(8) Main PID: 10712 (nginx) Tasks: 2 (limit: 3542) CGroup: /system.slice/nginx.service ├─10712 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; └─10713 nginx: worker process янв 06 13:54:14 ubuntu-lemp systemd[1]: Starting Высокопроизводительный веб-сервер и обратный прокси-сервер... янв 06 13:54:14 ubuntu-lemp systemd[1]: nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument янв 06 13:54:14 ubuntu-lemp systemd[1]: Started Высокопроизводительный веб-сервер и обратный прокси-сервер.
Кроме того, можно создать свой юнит-файл nginx.service
в каталоге /etc/systemd/system
, если использовать флаг full
для команды edit
. Этот файл будет иметь приоритет над определением юнита системы (обычно он находится где-то в /lib/systemd/system
).
$ sudo systemctl edit --full nginx.service
Чтобы удалить все сделанные изменения, из каталога /etc/systemd/system
нужно удалить файл nginx.service
и/или каталог nginx.service.d
:
$ sudo rm /etc/systemd/system/nginx.service $ sudo rm -r /etc/systemd/system/nginx.service.d
После удаления файла и/или каталога нужно перезагрузить процесс Systemd, чтобы система больше не пыталась использовать эти файлы и вернулась к использованию системных копий.
$ sudo systemctl daemon-reload