Version v1.0 (2010-12-28 11:43) [AUTO]
This commit is contained in:
943
s4a.tex
Normal file
943
s4a.tex
Normal file
@@ -0,0 +1,943 @@
|
||||
\documentclass[10pt,oneside,a4paper]{article}
|
||||
\usepackage{cmap} % Copy-paste из PDF без проблем с кодировкой
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[english,russian]{babel} % Русские переносы и проч.
|
||||
\usepackage[pdftex]{graphicx,color}
|
||||
\usepackage[T1,T2A]{fontenc}
|
||||
\usepackage{indentfirst} % Отступ в первом абзаце главы
|
||||
\usepackage{fancyvrb} % Продвинутые листинги и in-line commands
|
||||
% listings для данной ситуации, имхо, избыточен
|
||||
\usepackage{pdflscape}
|
||||
\usepackage[colorlinks,unicode,urlcolor=blue]{hyperref}
|
||||
% Заполняем поля PDF уже со включенной опцией unicode
|
||||
\hypersetup{pdftitle={systemd для администраторов},%
|
||||
pdfauthor={Lennart Poettering, Sergey Ptashnick}}
|
||||
% Небольшое сокращение
|
||||
\newcommand{\sectiona}[1]{\section*{#1}\addcontentsline{toc}{section}{#1}}
|
||||
% Настройка макета страницы
|
||||
\setlength{\hoffset}{-1.5cm}
|
||||
\addtolength{\textwidth}{2cm}
|
||||
\setlength{\voffset}{-1.5cm}
|
||||
\addtolength{\textheight}{2cm}
|
||||
% Настройка in-line commands
|
||||
\DefineShortVerb{\+}
|
||||
\VerbatimFootnotes
|
||||
% И листингов
|
||||
\definecolor{gray}{gray}{0.75}
|
||||
\fvset{frame=leftline,rulecolor=\color{gray},framerule=1mm}
|
||||
% Запрет висячих строк
|
||||
\clubpenalty=10000
|
||||
\widowpenalty=10000
|
||||
|
||||
\begin{document}
|
||||
\sloppy
|
||||
\title{systemd для администраторов}
|
||||
\author{Lennart P\"{o}ttering (author)\\Sergey Ptashnick (russian translation)\\%
|
||||
\small Licensed under
|
||||
\href{http://creativecommons.org/licenses/by-sa/3.0/legalcode}{CC-BY-SA}}
|
||||
\maketitle
|
||||
\tableofcontents%\newpage
|
||||
\sectiona{Предисловие автора}
|
||||
Многие из вас, наверное, уже знают, что
|
||||
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd}~--- это
|
||||
новая система инициализации дистрибутива Fedora, начиная с
|
||||
Fedora~14\footnote{Прим. перев.: к сожалению, разработчики Fedora приняли
|
||||
решение оставить в Fedora~14 в качестве системы инициалиазции по умолчанию
|
||||
upstart, однако systemd все равно будет включен в этот релиз и может быть
|
||||
использован в качестве альтернативной системы инициализации}. Помимо Fedora,
|
||||
systemd также поддерживает и другие дистрибутивы, в частности,
|
||||
\href{http://en.opensuse.org/SDB:Systemd}{OpenSUSE}.
|
||||
systemd предоставляет администраторам целый ряд новых возможностей,
|
||||
значительно упрощающих процесс обслуживания системы. Эта статья является
|
||||
первой в серии публикаций, планируемых в ближайшие месяцы. В каждой из этих
|
||||
статей я попытаюсь рассказать об очередной новой возможности systemd.
|
||||
Большинство этих возможностей можно описать легко и просто, и подобные статьи
|
||||
должны быть интересны довольно широкой аудитории. Однако, время от времени
|
||||
мы будем рассматривать ключевые новшества systemd, что может потребовать
|
||||
несколько более подробного изложения.
|
||||
\begin{flushright}
|
||||
Lennart P\"{o}ttering, 23 августа 2010
|
||||
\end{flushright}
|
||||
|
||||
\section{Контроль процесса загрузки}
|
||||
Как правило, во время загрузки Linux по экрану быстро пробегает огромное
|
||||
количество различных сообщений. Так как мы интенсивно работаем над
|
||||
параллелизацией и ускорением процесса загрузки, с каждой новой верисей
|
||||
systemd эти сообщения будут пробегать все быстрее и быстрее, вследствие чего,
|
||||
читать их будет все труднее. К тому же, многие пользователи применяют
|
||||
графические оболочки загрузки (например, Plymouth), полностью скрывающие эти
|
||||
сообщения. Тем не~менее, информация, которую несут эти сообщения, была и
|
||||
остается чрезвычайно важной — они показывают, успешно ли запустилась каждая
|
||||
служба, или попытка ее запуска закончилась ошибкой (зеленое
|
||||
\texttt{[~\textcolor{green}{OK}~]} или красное
|
||||
\texttt{[~\textcolor{red}{FAILED}~]} соответственно). Итак, с ростом скорости
|
||||
загрузки систем, возникает неприятная ситуация: информация о результатах
|
||||
запуска служб бывает очень важна, а просматривать ее все тяжелее. systemd
|
||||
предлагает выход из этой ситуации: он отслеживает и запоминает факты успешного
|
||||
или неудачного запуска служб на этапе загрузки, а такжи сбои служб во время
|
||||
работы. К таким случая относятся выходы с ненулевым кодом, ошибки
|
||||
сегментирования и т.п. Введя systemctl status в своей командной оболочке, вы
|
||||
можете ознакомиться с состоянием всех служб, как <<родных>> (native) для
|
||||
systemd, так и классических SysV/LSB служб, поддерживаемых в целях
|
||||
совместимости:
|
||||
|
||||
\begin{landscape}
|
||||
\begin{Verbatim}[fontsize=\small]
|
||||
[root@lambda] ~# systemctl
|
||||
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
|
||||
dev-hugepages.automount loaded active running Huge Pages File System Automount Point
|
||||
dev-mqueue.automount loaded active running POSIX Message Queue File System Automount Point
|
||||
proc-sys-fs-binfmt_misc.automount loaded active waiting Arbitrary Executable File Formats File System Automount Point
|
||||
sys-kernel-debug.automount loaded active waiting Debug File System Automount Point
|
||||
sys-kernel-security.automount loaded active waiting Security File System Automount Point
|
||||
sys-devices-pc...0000:02:00.0-net-eth0.device loaded active plugged 82573L Gigabit Ethernet Controller
|
||||
[...]
|
||||
sys-devices-virtual-tty-tty9.device loaded active plugged /sys/devices/virtual/tty/tty9
|
||||
-.mount loaded active mounted /
|
||||
boot.mount loaded active mounted /boot
|
||||
dev-hugepages.mount loaded active mounted Huge Pages File System
|
||||
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
|
||||
home.mount loaded active mounted /home
|
||||
proc-sys-fs-binfmt_misc.mount loaded active mounted Arbitrary Executable File Formats File System
|
||||
abrtd.service loaded active running ABRT Automated Bug Reporting Tool
|
||||
accounts-daemon.service loaded active running Accounts Service
|
||||
acpid.service loaded active running ACPI Event Daemon
|
||||
atd.service loaded active running Execution Queue Daemon
|
||||
auditd.service loaded active running Security Auditing Service
|
||||
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
|
||||
bluetooth.service loaded active running Bluetooth Manager
|
||||
console-kit-daemon.service loaded active running Console Manager
|
||||
cpuspeed.service loaded active exited LSB: processor frequency scaling support
|
||||
crond.service loaded active running Command Scheduler
|
||||
cups.service loaded active running CUPS Printing Service
|
||||
dbus.service loaded active running D-Bus System Message Bus
|
||||
getty@tty2.service loaded active running Getty on tty2
|
||||
getty@tty3.service loaded active running Getty on tty3
|
||||
getty@tty4.service loaded active running Getty on tty4
|
||||
getty@tty5.service loaded active running Getty on tty5
|
||||
getty@tty6.service loaded active running Getty on tty6
|
||||
haldaemon.service loaded active running Hardware Manager
|
||||
hdapsd@sda.service loaded active running sda shock protection daemon
|
||||
irqbalance.service loaded active running LSB: start and stop irqbalance daemon
|
||||
iscsi.service loaded active exited LSB: Starts and stops login and scanning of iSCSI devices.
|
||||
iscsid.service loaded active exited LSB: Starts and stops login iSCSI daemon.
|
||||
livesys-late.service loaded active exited LSB: Late init script for live image.
|
||||
livesys.service loaded active exited LSB: Init script for live image.
|
||||
lvm2-monitor.service loaded active exited LSB: Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
|
||||
mdmonitor.service loaded active running LSB: Start and stop the MD software RAID monitor
|
||||
modem-manager.service loaded active running Modem Manager
|
||||
netfs.service loaded active exited LSB: Mount and unmount network filesystems.
|
||||
NetworkManager.service loaded active running Network Manager
|
||||
ntpd.service loaded maintenance maintenance Network Time Service
|
||||
polkitd.service loaded active running Policy Manager
|
||||
prefdm.service loaded active running Display Manager
|
||||
rc-local.service loaded active exited /etc/rc.local Compatibility
|
||||
rpcbind.service loaded active running RPC Portmapper Service
|
||||
rsyslog.service loaded active running System Logging Service
|
||||
rtkit-daemon.service loaded active running RealtimeKit Scheduling Policy Service
|
||||
sendmail.service loaded active running LSB: start and stop sendmail
|
||||
sshd@172.31.0.53:22-172.31.0.4:36368.service loaded active running SSH Per-Connection Server
|
||||
sysinit.service loaded active running System Initialization
|
||||
systemd-logger.service loaded active running systemd Logging Daemon
|
||||
udev-post.service loaded active exited LSB: Moves the generated persistent udev rules to /etc/udev/rules.d
|
||||
udisks.service loaded active running Disk Manager
|
||||
upowerd.service loaded active running Power Manager
|
||||
wpa_supplicant.service loaded active running Wi-Fi Security Service
|
||||
avahi-daemon.socket loaded active listening Avahi mDNS/DNS-SD Stack Activation Socket
|
||||
cups.socket loaded active listening CUPS Printing Service Sockets
|
||||
dbus.socket loaded active running dbus.socket
|
||||
rpcbind.socket loaded active listening RPC Portmapper Socket
|
||||
sshd.socket loaded active listening sshd.socket
|
||||
systemd-initctl.socket loaded active listening systemd /dev/initctl Compatibility Socket
|
||||
systemd-logger.socket loaded active running systemd Logging Socket
|
||||
systemd-shutdownd.socket loaded active listening systemd Delayed Shutdown Socket
|
||||
dev-disk-by\x1...x1db22a\x1d870f1adf2732.swap loaded active active /dev/disk/by-uuid/fd626ef7-34a4-4958-b22a-870f1adf2732
|
||||
basic.target loaded active active Basic System
|
||||
bluetooth.target loaded active active Bluetooth
|
||||
dbus.target loaded active active D-Bus
|
||||
getty.target loaded active active Login Prompts
|
||||
graphical.target loaded active active Graphical Interface
|
||||
local-fs.target loaded active active Local File Systems
|
||||
multi-user.target loaded active active Multi-User
|
||||
network.target loaded active active Network
|
||||
remote-fs.target loaded active active Remote File Systems
|
||||
sockets.target loaded active active Sockets
|
||||
swap.target loaded active active Swap
|
||||
sysinit.target loaded active active System Initialization
|
||||
|
||||
LOAD = Reflects whether the unit definition was properly loaded.
|
||||
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
|
||||
SUB = The low-level unit activation state, values depend on unit type.
|
||||
JOB = Pending job for the unit.
|
||||
|
||||
221 units listed. Pass --all to see inactive units, too.
|
||||
[root@lambda] ~#
|
||||
\end{Verbatim}
|
||||
(Листинг был сокращен за счет удаления строк, не~относящихся к теме статьи.)
|
||||
\end{landscape}
|
||||
|
||||
Обратите внимание на графу ACTIVE, в которой отображается обобщенный статус
|
||||
службы (или любого другого юнита systemd: устройства, сокета, точки
|
||||
монтирования~--- их мы рассмотрим подробнее в последующих статьях). Основными
|
||||
значениями обощенного статуса являются active (служба выполняется) и inactive
|
||||
(служба не~была запущена). Также существуют и другие статусы. Например,
|
||||
внимательно посмотрев на листинг выше, вы можете заметить, что служба ntpd
|
||||
(сервер точного времени) находится в состоянии, обозначенном как maintenance.
|
||||
Чтобы узнать, что же произошло с ntpd, воспользуемся командой
|
||||
+systemctl status+:
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
[root@lambda] ~# systemctl status ntpd.service
|
||||
ntpd.service - Network Time Service
|
||||
Loaded: loaded (/etc/systemd/system/ntpd.service)
|
||||
Active: \textcolor{red}{maintenance}
|
||||
Main: 953 (code=exited, status=255)
|
||||
CGroup: name=systemd:/systemd-1/ntpd.service
|
||||
[root@lambda] ~#
|
||||
\end{Verbatim}
|
||||
|
||||
systemd сообщает нам, что ntpd был запущен (с идентификатором процесса 953) и
|
||||
аварийно завершил работу (с кодом выхода 255).
|
||||
|
||||
В последующих версиях systemd, мы планируем добавить возможность вызова в
|
||||
таких ситуациях ABRT (Automated Bug Report Tool), но для этого необходима
|
||||
соответствующая поддержка со стороны самого ABRT. Соответствующий запрос уже
|
||||
\href{https://bugzilla.redhat.com/show_bug.cgi?id=622773}{направлен} его
|
||||
разработчикам, однако пока не~встретил среди них поддержки.
|
||||
|
||||
Резюме: использование +systemctl+ и +systemctl status+ представляет современную,
|
||||
более удобную и эффективную альтернативу разглядыванию быстро пробегающих по
|
||||
экрану сообщений в классическом SysV. +systemctl status+ дает возможность
|
||||
получить развернутую информацию о характере ошибки и, кроме того, в отличие
|
||||
от сообщений SysV, показывает не~только ошибки при запуске, но и ошибки,
|
||||
возникшие во время исполнения службы.
|
||||
|
||||
\section{О службах и процессах}
|
||||
В большинстве современных Linux-систем количество одновременно работающих
|
||||
процессов обычно весьма значительно. Понять, откуда взялся и что делает тот
|
||||
или иной процесс, становится все сложнее и сложнее. Многие службы используют
|
||||
сразу несколько рабочих процессов, и это отнюдь не~всегда можно легко
|
||||
распознать по выводу команды ps. Встречаются еще более сложные ситуации,
|
||||
когда демон запускает сторонние процессы~--- например, веб-сервер выполняет
|
||||
CGI-программы, а демон cron~--- команды, предписанные ему в crontab.
|
||||
|
||||
Немного помочь в решении этой проблемы может древовидная иерархия процессов,
|
||||
отображаемая по команде +ps xaf+. Именно <<немного помочь>>, а не~решить
|
||||
полностью. В частности, процессы, родители которых умирают раньше их самих,
|
||||
становят потомками PID~1 (процесса init), что сразу затрудняет процесс
|
||||
выяснения их происхождения. Кроме того, процесс может избавиться от связи с
|
||||
родителем через две последовательные операции +fork()+ (В целом, эта возможность
|
||||
признается нужной и полезной, и является частью используемого в Unix подхода
|
||||
к разработке демонов.) Также, не~будем забывать, что процесс легко может
|
||||
изменить свое имя посредством +PR_SETNAME+, или задав значение
|
||||
+argv[0]+, что также усложняет процесс его опознания\footnote{Прим.
|
||||
перев.: стоит отметить, что перечисленные ситуации могут возникнуть не~только
|
||||
вследствие ошибок в коде и/или конфигурации программ, но и в результате злого
|
||||
умысла. Например, очень часто встречается ситуация, когда установленный на
|
||||
взломанном сервере процесс-бэкдор маскируется под нормального демона, меняя
|
||||
себе имя, скажем, на httpd}.
|
||||
|
||||
systemd предоставляет простой путь для решения обсуждаемой задачи. Запуская
|
||||
очередной новый процесс, systemd помещает его в отдельную контрольную группу
|
||||
с соответствующим именем. Контрольные группы Linux предоставляют очень
|
||||
удобный инструмент для иерархической структуризации процессов: когда
|
||||
какой-либо процесс порождает потомка, этот потомок автоматически включается в
|
||||
ту же группу, что и родитель. При этом, что очень важно, непривилегированные
|
||||
процессы не~могут изменить свое положение в этой иерархии. Таким образом,
|
||||
контрольные группы позволяют точно установить происхождение конкретного
|
||||
процесса, вне зависимости от того, сколько раз он форкался и переименовывал
|
||||
себя~--- имя его контрольной группы невозможно спрятать или изменить. Кроме
|
||||
того, при штатном завершении родительской службы, будут завершены и все
|
||||
порожденные ею процессы, как бы они ни пытались сбежать. С systemd уже
|
||||
невозможна ситуация, когда после остановки web-сервера, некорректно
|
||||
форкнувшийся CGI-процесс продолжает исполняться вплоть до последних секунд
|
||||
работы системы.
|
||||
|
||||
В этой статье мы рассмотрим две простых команды, которые позволят вам
|
||||
наглядно увидеть схему взаимоотношений systemd и порожденных им процессов.
|
||||
Первая из этих команд~--- все та же +ps+, однако на этот раз в ее параметры
|
||||
добавлено указание выводить сведения по контрольным группам, а также другую
|
||||
интересную информацию:
|
||||
|
||||
\begin{landscape}
|
||||
\begin{Verbatim}[fontsize=\small]
|
||||
$ ps xawf -eo pid,user,cgroup,args
|
||||
PID USER CGROUP COMMAND
|
||||
2 root - [kthreadd]
|
||||
3 root - \_ [ksoftirqd/0]
|
||||
[...]
|
||||
4281 root - \_ [flush-8:0]
|
||||
1 root name=systemd:/systemd-1 /sbin/init
|
||||
455 root name=systemd:/systemd-1/sysinit.service /sbin/udevd -d
|
||||
28188 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
|
||||
28191 root name=systemd:/systemd-1/sysinit.service \_ /sbin/udevd -d
|
||||
1096 dbus name=systemd:/systemd-1/dbus.service /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
|
||||
1131 root name=systemd:/systemd-1/auditd.service auditd
|
||||
1133 root name=systemd:/systemd-1/auditd.service \_ /sbin/audispd
|
||||
1135 root name=systemd:/systemd-1/auditd.service \_ /usr/sbin/sedispatch
|
||||
1171 root name=systemd:/systemd-1/NetworkManager.service /usr/sbin/NetworkManager --no-daemon
|
||||
4028 root name=systemd:/systemd-1/NetworkManager.service \_ /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -
|
||||
1175 avahi name=systemd:/systemd-1/avahi-daemon.service avahi-daemon: running [epsilon.local]
|
||||
1194 avahi name=systemd:/systemd-1/avahi-daemon.service \_ avahi-daemon: chroot helper
|
||||
1193 root name=systemd:/systemd-1/rsyslog.service /sbin/rsyslogd -c 4
|
||||
1195 root name=systemd:/systemd-1/cups.service cupsd -C /etc/cups/cupsd.conf
|
||||
1207 root name=systemd:/systemd-1/mdmonitor.service mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
|
||||
1210 root name=systemd:/systemd-1/irqbalance.service irqbalance
|
||||
1216 root name=systemd:/systemd-1/dbus.service /usr/sbin/modem-manager
|
||||
1219 root name=systemd:/systemd-1/dbus.service /usr/libexec/polkit-1/polkitd
|
||||
1242 root name=systemd:/systemd-1/dbus.service /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
|
||||
1249 68 name=systemd:/systemd-1/haldaemon.service hald
|
||||
1250 root name=systemd:/systemd-1/haldaemon.service \_ hald-runner
|
||||
1273 root name=systemd:/systemd-1/haldaemon.service \_ hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
|
||||
1275 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-rfkill-killswitch
|
||||
1284 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-leds
|
||||
1285 root name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-generic-backlight
|
||||
1287 68 name=systemd:/systemd-1/haldaemon.service \_ /usr/libexec/hald-addon-acpi
|
||||
1317 root name=systemd:/systemd-1/abrtd.service /usr/sbin/abrtd -d -s
|
||||
1332 root name=systemd:/systemd-1/getty@.service/tty2 /sbin/mingetty tty2
|
||||
1339 root name=systemd:/systemd-1/getty@.service/tty3 /sbin/mingetty tty3
|
||||
1342 root name=systemd:/systemd-1/getty@.service/tty5 /sbin/mingetty tty5
|
||||
1343 root name=systemd:/systemd-1/getty@.service/tty4 /sbin/mingetty tty4
|
||||
1344 root name=systemd:/systemd-1/crond.service crond
|
||||
1346 root name=systemd:/systemd-1/getty@.service/tty6 /sbin/mingetty tty6
|
||||
1362 root name=systemd:/systemd-1/sshd.service /usr/sbin/sshd
|
||||
1376 root name=systemd:/systemd-1/prefdm.service /usr/sbin/gdm-binary -nodaemon
|
||||
1391 root name=systemd:/systemd-1/prefdm.service \_ /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
|
||||
1394 root name=systemd:/systemd-1/prefdm.service \_ /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
|
||||
1495 root name=systemd:/user/lennart/1 \_ pam: gdm-password
|
||||
1521 lennart name=systemd:/user/lennart/1 \_ gnome-session
|
||||
1621 lennart name=systemd:/user/lennart/1 \_ metacity
|
||||
1635 lennart name=systemd:/user/lennart/1 \_ gnome-panel
|
||||
1638 lennart name=systemd:/user/lennart/1 \_ nautilus
|
||||
1640 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/polkit-gnome-authentication-agent-1
|
||||
1641 lennart name=systemd:/user/lennart/1 \_ /usr/bin/seapplet
|
||||
1644 lennart name=systemd:/user/lennart/1 \_ gnome-volume-control-applet
|
||||
1646 lennart name=systemd:/user/lennart/1 \_ /usr/sbin/restorecond -u
|
||||
1652 lennart name=systemd:/user/lennart/1 \_ /usr/bin/devilspie
|
||||
1662 lennart name=systemd:/user/lennart/1 \_ nm-applet --sm-disable
|
||||
1664 lennart name=systemd:/user/lennart/1 \_ gnome-power-manager
|
||||
1665 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/gdu-notification-daemon
|
||||
1670 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/evolution/2.32/evolution-alarm-notify
|
||||
1672 lennart name=systemd:/user/lennart/1 \_ /usr/bin/python /usr/share/system-config-printer/applet.py
|
||||
1674 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/deja-dup/deja-dup-monitor
|
||||
1675 lennart name=systemd:/user/lennart/1 \_ abrt-applet
|
||||
1677 lennart name=systemd:/user/lennart/1 \_ bluetooth-applet
|
||||
1678 lennart name=systemd:/user/lennart/1 \_ gpk-update-icon
|
||||
1408 root name=systemd:/systemd-1/console-kit-daemon.service /usr/sbin/console-kit-daemon --no-daemon
|
||||
1419 gdm name=systemd:/systemd-1/prefdm.service /usr/bin/dbus-launch --exit-with-session
|
||||
1453 root name=systemd:/systemd-1/dbus.service /usr/libexec/upowerd
|
||||
1473 rtkit name=systemd:/systemd-1/rtkit-daemon.service /usr/libexec/rtkit-daemon
|
||||
1496 root name=systemd:/systemd-1/accounts-daemon.service /usr/libexec/accounts-daemon
|
||||
1499 root name=systemd:/systemd-1/systemd-logger.service /lib/systemd/systemd-logger
|
||||
1511 lennart name=systemd:/systemd-1/prefdm.service /usr/bin/gnome-keyring-daemon --daemonize --login
|
||||
1534 lennart name=systemd:/user/lennart/1 dbus-launch --sh-syntax --exit-with-session
|
||||
1535 lennart name=systemd:/user/lennart/1 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
|
||||
1603 lennart name=systemd:/user/lennart/1 /usr/libexec/gconfd-2
|
||||
1612 lennart name=systemd:/user/lennart/1 /usr/libexec/gnome-settings-daemon
|
||||
1615 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd
|
||||
1626 lennart name=systemd:/user/lennart/1 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
|
||||
1634 lennart name=systemd:/user/lennart/1 /usr/bin/pulseaudio --start --log-target=syslog
|
||||
1649 lennart name=systemd:/user/lennart/1 \_ /usr/libexec/pulse/gconf-helper
|
||||
1645 lennart name=systemd:/user/lennart/1 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
|
||||
1668 lennart name=systemd:/user/lennart/1 /usr/libexec/im-settings-daemon
|
||||
1701 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-gdu-volume-monitor
|
||||
1707 lennart name=systemd:/user/lennart/1 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
|
||||
1725 lennart name=systemd:/user/lennart/1 /usr/libexec/clock-applet
|
||||
1727 lennart name=systemd:/user/lennart/1 /usr/libexec/wnck-applet
|
||||
1729 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-area-applet
|
||||
1733 root name=systemd:/systemd-1/dbus.service /usr/libexec/udisks-daemon
|
||||
1747 root name=systemd:/systemd-1/dbus.service \_ udisks-daemon: polling /dev/sr0
|
||||
1759 lennart name=systemd:/user/lennart/1 gnome-screensaver
|
||||
1780 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
|
||||
1864 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfs-afc-volume-monitor
|
||||
1874 lennart name=systemd:/user/lennart/1 /usr/libexec/gconf-im-settings-daemon
|
||||
1903 lennart name=systemd:/user/lennart/1 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
|
||||
1909 lennart name=systemd:/user/lennart/1 gnome-terminal
|
||||
1913 lennart name=systemd:/user/lennart/1 \_ gnome-pty-helper
|
||||
1914 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
29231 lennart name=systemd:/user/lennart/1 | \_ ssh tango
|
||||
2221 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
4193 lennart name=systemd:/user/lennart/1 | \_ ssh tango
|
||||
2461 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
29219 lennart name=systemd:/user/lennart/1 | \_ emacs systemd-for-admins-1.txt
|
||||
15113 lennart name=systemd:/user/lennart/1 \_ bash
|
||||
27251 lennart name=systemd:/user/lennart/1 \_ empathy
|
||||
29504 lennart name=systemd:/user/lennart/1 \_ ps xawf -eo pid,user,cgroup,args
|
||||
1968 lennart name=systemd:/user/lennart/1 ssh-agent
|
||||
1994 lennart name=systemd:/user/lennart/1 gpg-agent --daemon --write-env-file
|
||||
18679 lennart name=systemd:/user/lennart/1 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
|
||||
18741 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/firefox-3.6/firefox
|
||||
28900 lennart name=systemd:/user/lennart/1 \_ /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
|
||||
4016 root name=systemd:/systemd-1/sysinit.service /usr/sbin/bluetoothd --udev
|
||||
4094 smmsp name=systemd:/systemd-1/sendmail.service sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
|
||||
4096 root name=systemd:/systemd-1/sendmail.service sendmail: accepting connections
|
||||
4112 ntp name=systemd:/systemd-1/ntpd.service /usr/sbin/ntpd -n -u ntp:ntp -g
|
||||
27262 lennart name=systemd:/user/lennart/1 /usr/libexec/mission-control-5
|
||||
27265 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-haze
|
||||
27268 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-logger
|
||||
27270 lennart name=systemd:/user/lennart/1 /usr/libexec/dconf-service
|
||||
27280 lennart name=systemd:/user/lennart/1 /usr/libexec/notification-daemon
|
||||
27284 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-gabble
|
||||
27285 lennart name=systemd:/user/lennart/1 /usr/libexec/telepathy-salut
|
||||
27297 lennart name=systemd:/user/lennart/1 /usr/libexec/geoclue-yahoo
|
||||
\end{Verbatim}
|
||||
(Данный листинг был сокращен за счет удаления из него строк, относящихся к
|
||||
потокам ядра, так как они никак не~относятся к обсуждаемой нами теме.)
|
||||
\end{landscape}
|
||||
|
||||
Обратите внимание на третий столбец, показывающий имя контрольной группы,
|
||||
которое systemd присваивает каждому процессу. Например, процесс +udev+
|
||||
находится в группе +name=systemd:/systemd-1/sysinit.service+. В эту группу
|
||||
помещаются процессы, запущенные службой +sysinit.service+, которая запускается
|
||||
на ранней стадии загрузки.
|
||||
|
||||
Вы можете очень сильно упростить себе работу, если назначите для
|
||||
вышеприведенной команды какой-нибудь простой и короткий псевдоним, например
|
||||
\begin{Verbatim}
|
||||
alias psc='ps xawf -eo pid,user,cgroup,args'
|
||||
\end{Verbatim}
|
||||
---~теперь для получения исчерпывающей информации по процессам достаточно будет
|
||||
нажать всего четыре клавиши.
|
||||
|
||||
Альтернативый способ получить ту же информацию~--- воспользоваться утилитой
|
||||
+systemd-cgls+, входящей в комплект поставки systemd. Она отображает иерархию
|
||||
контрольных групп в виде превдографической диаграммы-дерева:
|
||||
|
||||
\begin{landscape}
|
||||
\begin{Verbatim}[fontsize=\small]
|
||||
$ systemd-cgls
|
||||
+ 2 [kthreadd]
|
||||
[...]
|
||||
+ 4281 [flush-8:0]
|
||||
+ user
|
||||
| \ lennart
|
||||
| \ 1
|
||||
| + 1495 pam: gdm-password
|
||||
| + 1521 gnome-session
|
||||
| + 1534 dbus-launch --sh-syntax --exit-with-session
|
||||
| + 1535 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
|
||||
| + 1603 /usr/libexec/gconfd-2
|
||||
| + 1612 /usr/libexec/gnome-settings-daemon
|
||||
| + 1615 /ushr/libexec/gvfsd
|
||||
| + 1621 metacity
|
||||
| + 1626 /usr/libexec//gvfs-fuse-daemon /home/lennart/.gvfs
|
||||
| + 1634 /usr/bin/pulseaudio --start --log-target=syslog
|
||||
| + 1635 gnome-panel
|
||||
| + 1638 nautilus
|
||||
| + 1640 /usr/libexec/polkit-gnome-authentication-agent-1
|
||||
| + 1641 /usr/bin/seapplet
|
||||
| + 1644 gnome-volume-control-applet
|
||||
| + 1645 /usr/libexec/bonobo-activation-server --ac-activate --ior-output-fd=24
|
||||
| + 1646 /usr/sbin/restorecond -u
|
||||
| + 1649 /usr/libexec/pulse/gconf-helper
|
||||
| + 1652 /usr/bin/devilspie
|
||||
| + 1662 nm-applet --sm-disable
|
||||
| + 1664 gnome-power-manager
|
||||
| + 1665 /usr/libexec/gdu-notification-daemon
|
||||
| + 1668 /usr/libexec/im-settings-daemon
|
||||
| + 1670 /usr/libexec/evolution/2.32/evolution-alarm-notify
|
||||
| + 1672 /usr/bin/python /usr/share/system-config-printer/applet.py
|
||||
| + 1674 /usr/lib64/deja-dup/deja-dup-monitor
|
||||
| + 1675 abrt-applet
|
||||
| + 1677 bluetooth-applet
|
||||
| + 1678 gpk-update-icon
|
||||
| + 1701 /usr/libexec/gvfs-gdu-volume-monitor
|
||||
| + 1707 /usr/bin/gnote --panel-applet --oaf-activate-iid=OAFIID:GnoteApplet_Factory --oaf-ior-fd=22
|
||||
| + 1725 /usr/libexec/clock-applet
|
||||
| + 1727 /usr/libexec/wnck-applet
|
||||
| + 1729 /usr/libexec/notification-area-applet
|
||||
| + 1759 gnome-screensaver
|
||||
| + 1780 /usr/libexec/gvfsd-trash --spawner :1.9 /org/gtk/gvfs/exec_spaw/0
|
||||
| + 1864 /usr/libexec/gvfs-afc-volume-monitor
|
||||
| + 1874 /usr/libexec/gconf-im-settings-daemon
|
||||
| + 1882 /usr/libexec/gvfs-gphoto2-volume-monitor
|
||||
| + 1903 /usr/libexec/gvfsd-burn --spawner :1.9 /org/gtk/gvfs/exec_spaw/1
|
||||
| + 1909 gnome-terminal
|
||||
| + 1913 gnome-pty-helper
|
||||
| + 1914 bash
|
||||
| + 1968 ssh-agent
|
||||
| + 1994 gpg-agent --daemon --write-env-file
|
||||
| + 2221 bash
|
||||
| + 2461 bash
|
||||
| + 4193 ssh tango
|
||||
| + 15113 bash
|
||||
| + 18679 /bin/sh /usr/lib64/firefox-3.6/run-mozilla.sh /usr/lib64/firefox-3.6/firefox
|
||||
| + 18741 /usr/lib64/firefox-3.6/firefox
|
||||
| + 27251 empathy
|
||||
| + 27262 /usr/libexec/mission-control-5
|
||||
| + 27265 /usr/libexec/telepathy-haze
|
||||
| + 27268 /usr/libexec/telepathy-logger
|
||||
| + 27270 /usr/libexec/dconf-service
|
||||
| + 27280 /usr/libexec/notification-daemon
|
||||
| + 27284 /usr/libexec/telepathy-gabble
|
||||
| + 27285 /usr/libexec/telepathy-salut
|
||||
| + 27297 /usr/libexec/geoclue-yahoo
|
||||
| + 28900 /usr/lib64/nspluginwrapper/npviewer.bin --plugin /usr/lib64/mozilla/plugins/libflashplayer.so --connection /org/wrapper/NSPlugins/libflashplayer.so/18741-6
|
||||
| + 29219 emacs systemd-for-admins-1.txt
|
||||
| + 29231 ssh tango
|
||||
| \ 29519 systemd-cgls
|
||||
\ systemd-1
|
||||
+ 1 /sbin/init
|
||||
+ ntpd.service
|
||||
| \ 4112 /usr/sbin/ntpd -n -u ntp:ntp -g
|
||||
+ systemd-logger.service
|
||||
| \ 1499 /lib/systemd/systemd-logger
|
||||
+ accounts-daemon.service
|
||||
| \ 1496 /usr/libexec/accounts-daemon
|
||||
+ rtkit-daemon.service
|
||||
| \ 1473 /usr/libexec/rtkit-daemon
|
||||
+ console-kit-daemon.service
|
||||
| \ 1408 /usr/sbin/console-kit-daemon --no-daemon
|
||||
+ prefdm.service
|
||||
| + 1376 /usr/sbin/gdm-binary -nodaemon
|
||||
| + 1391 /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 --force-active-vt
|
||||
| + 1394 /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-f2KUOh/database -nolisten tcp vt1
|
||||
| + 1419 /usr/bin/dbus-launch --exit-with-session
|
||||
| \ 1511 /usr/bin/gnome-keyring-daemon --daemonize --login
|
||||
+ getty@.service
|
||||
| + tty6
|
||||
| | \ 1346 /sbin/mingetty tty6
|
||||
| + tty4
|
||||
| | \ 1343 /sbin/mingetty tty4
|
||||
| + tty5
|
||||
| | \ 1342 /sbin/mingetty tty5
|
||||
| + tty3
|
||||
| | \ 1339 /sbin/mingetty tty3
|
||||
| \ tty2
|
||||
| \ 1332 /sbin/mingetty tty2
|
||||
+ abrtd.service
|
||||
| \ 1317 /usr/sbin/abrtd -d -s
|
||||
+ crond.service
|
||||
| \ 1344 crond
|
||||
+ sshd.service
|
||||
| \ 1362 /usr/sbin/sshd
|
||||
+ sendmail.service
|
||||
| + 4094 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
|
||||
| \ 4096 sendmail: accepting connections
|
||||
+ haldaemon.service
|
||||
| + 1249 hald
|
||||
| + 1250 hald-runner
|
||||
| + 1273 hald-addon-input: Listening on /dev/input/event3 /dev/input/event9 /dev/input/event1 /dev/input/event7 /dev/input/event2 /dev/input/event0 /dev/input/event8
|
||||
| + 1275 /usr/libexec/hald-addon-rfkill-killswitch
|
||||
| + 1284 /usr/libexec/hald-addon-leds
|
||||
| + 1285 /usr/libexec/hald-addon-generic-backlight
|
||||
| \ 1287 /usr/libexec/hald-addon-acpi
|
||||
+ irqbalance.service
|
||||
| \ 1210 irqbalance
|
||||
+ avahi-daemon.service
|
||||
| + 1175 avahi-daemon: running [epsilon.local]
|
||||
+ NetworkManager.service
|
||||
| + 1171 /usr/sbin/NetworkManager --no-daemon
|
||||
| \ 4028 /sbin/dhclient -d -4 -sf /usr/libexec/nm-dhcp-client.action -pf /var/run/dhclient-wlan0.pid -lf /var/lib/dhclient/dhclient-7d32a784-ede9-4cf6-9ee3-60edc0bce5ff-wlan0.lease -cf /var/run/nm-dhclient-wlan0.conf wlan0
|
||||
+ rsyslog.service
|
||||
| \ 1193 /sbin/rsyslogd -c 4
|
||||
+ mdmonitor.service
|
||||
| \ 1207 mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
|
||||
+ cups.service
|
||||
| \ 1195 cupsd -C /etc/cups/cupsd.conf
|
||||
+ auditd.service
|
||||
| + 1131 auditd
|
||||
| + 1133 /sbin/audispd
|
||||
| \ 1135 /usr/sbin/sedispatch
|
||||
+ dbus.service
|
||||
| + 1096 /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation
|
||||
| + 1216 /usr/sbin/modem-manager
|
||||
| + 1219 /usr/libexec/polkit-1/polkitd
|
||||
| + 1242 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid
|
||||
| + 1453 /usr/libexec/upowerd
|
||||
| + 1733 /usr/libexec/udisks-daemon
|
||||
| + 1747 udisks-daemon: polling /dev/sr0
|
||||
| \ 29509 /usr/libexec/packagekitd
|
||||
+ dev-mqueue.mount
|
||||
+ dev-hugepages.mount
|
||||
\ sysinit.service
|
||||
+ 455 /sbin/udevd -d
|
||||
+ 4016 /usr/sbin/bluetoothd --udev
|
||||
+ 28188 /sbin/udevd -d
|
||||
\ 28191 /sbin/udevd -d
|
||||
\end{Verbatim}
|
||||
(Как и предыдущий, этот листинг был сокращен за счет удаления перечня потоков
|
||||
ядра.)
|
||||
\end{landscape}
|
||||
|
||||
Как видно из листинга, данная команда наглядно показывает принадлежность
|
||||
процессов к их контрольным группам, а следовательно, и к службам, так как
|
||||
systemd именует группы в соответствии с названиями служб. Например, из
|
||||
приведенного листинга нетрудно понять, что служба системного аудита
|
||||
+auditd.service+ порождает три отдельных процесса: +auditd+,
|
||||
+audisp+ и +sedispatch+.
|
||||
|
||||
Внимательно посмотрев на листинг, можно заметить, что некоторые процессы
|
||||
помещены в группу +/user/lennart/1+. Дело в том, что systemd занимается
|
||||
отслежванием и группировкой не~только процессов, относящихся к системным
|
||||
службам, но и процессов, запущенных в рамках пользовательских сеансов. В
|
||||
последующих статьях мы обсудим этот вопрос более подробно.
|
||||
|
||||
\section{HOW-TO: преобразование SysV init-скрипта в systemd service-файл}
|
||||
|
||||
Традиционно, службы Unix и Linux (демоны) запускаются через SysV init-скрипты.
|
||||
Эти скрипты пишутся на языке Bourne Shell (+/bin/sh+), располагаются в
|
||||
специальном каталоге (обычно +/etc/rc.d/init.d/+) и вызываются с одним из
|
||||
стандартных параметров (+start+, +stop+, +reload+ и т.п.)~--- таким образом
|
||||
указывается действие, которое необходимо прозвести над службой (запустить,
|
||||
остановить, заставить перечитать конфигурацию). При запуске службы такой
|
||||
скрипт, как правило, вызывает бинарник демона, который, в свою очередь,
|
||||
форкается, порождая фоновый процесс (т.е. демонизируется). Заметим, что
|
||||
shell-скрипты, как правило, отличается низкой скоростью работы, излишней
|
||||
подробностью изложения и крайней хрупкостью. Читать их, из-за изобилия
|
||||
всевозможного вспомогательного и дополнительного кода, чрезвычайно тяжело.
|
||||
Впрочем, нельзя не~упомянуть, что эти скрипты являются очень гибким
|
||||
инструментом (ведь, по сути, это всего лишь код, который можно модифицировать
|
||||
как угодно). С другой стороны, многие задачи, возникающие при работе со
|
||||
службами, бывает довольно тяжело решить средствами shell-скриптов. К таким
|
||||
задачам относятся: огранизация параллельного исполнения, корректное
|
||||
отслеживание процессов, конфигурирование различных параметров среды исполнения
|
||||
процесса. systemd обеспечивает совместимость с init-скриптами, однако, с учетом
|
||||
описанных выше их недостатков, более правильным решением будет использование
|
||||
штатных service-файлов systemd для всех установленных в системе служб. Стоит
|
||||
отметить что, в отличие от init-скриптов, которые часто приходится
|
||||
модифицировать при переносе из одного дистриубтива в другой, один и тот же
|
||||
service-файл будет работать в любом дистрибутиве, использующем systemd (а таких
|
||||
дистрибутивов с каждым днем становится все больше и больше). Далее мы вкратце
|
||||
рассмотрим процесс преобразования SysV init-скрипта в service-файл systemd.
|
||||
Вообще говоря, service-файл должен создаваться разработчиками каждого демона, и
|
||||
включаться в комплект его поставки. Если вам удалось успешно создать
|
||||
работоспособный service-файл для какого-либо демона, настоятельно рекомендуем
|
||||
вам отправить этот файл разработчикам. Вопросы по полноценной интеграции
|
||||
демонов с systemd, с максимальным использованием всех его возможностей, будут
|
||||
рассмотрены в последующих статьях этого цикла, пока же ограничимся ссылкой на
|
||||
\href{http://0pointer.de/public/systemd-man/daemon.html}{страницу} официальной
|
||||
документации.
|
||||
|
||||
Итак, приступим. В качестве пример возьмем init-скрипт демона ABRT (Automatic
|
||||
Bug Reporting Tool, службы, занимающейся сбором crash dump'ов). Исходный
|
||||
скрипт (в варианте для дистрибутива Fedora) можно загрузить
|
||||
\href{http://0pointer.de/public/abrtd}{здесь}.
|
||||
|
||||
Начнем с того, что прочитаем исходный скрипт (неожиданный ход, правда?) и
|
||||
выделим полезную информацию из груды хлама. Практически у всех init-скриптов
|
||||
большая часть кода является чисто вспомогательной, и мало чем отличается от
|
||||
одного скрипта к другому. Как правило, при создании новых скриптов этот код
|
||||
просто копируется из уже существующих (разработка в стиле copy-paste). Итак,
|
||||
в исследуемом скрипте нас интересует следующая информация:
|
||||
|
||||
\begin{itemize}
|
||||
\item Строка описания службы: <<Daemon to detect crashing apps>>. Как
|
||||
нетрудно заметить, комментарии в заголовке скрипта весьма
|
||||
пространны и описывают не~сколько саму службу, сколько
|
||||
скрипт, ее запускающий. service-файлы systemd также включают
|
||||
описание, но оно относится исключительно к службе, а не~к
|
||||
service-файлу.
|
||||
\item LSB-заголовок\footnote{LSB-заголовок~--- определенная в
|
||||
\href{http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html}{Linux
|
||||
Standard Base} схема записи метаданных о службах в блоках
|
||||
комментариев соответствующих init-скриптов. Изначально эта
|
||||
схема была введена именно для того, чтобы стандартизировать
|
||||
init-скрипты во всех дистрибутивах. Однако разработчики
|
||||
многих дистрибутивов не~считают нужным точное исполнение
|
||||
требований LSB, и поэтому формы представления метаданных в
|
||||
различных дистрибутивах могут отличаться. Вследствие этого,
|
||||
при переносе init-скрипта из одного дистрибутива в другой,
|
||||
скрипт приходится модифицировать. Например, демон пересылки
|
||||
почты при описании зависимостей может именоваться
|
||||
+MTA+ или +smtpdaemon+ (Fedora), +smtp+
|
||||
(openSUSE), +mail-transport-agent+ (Debian и Ubuntu),
|
||||
+mail-transfer-agent+. Таким образом,
|
||||
стандарт LSB не~справляется с поставленной задачей},
|
||||
содержащий информацию о зависимостях. systemd, базирующийся
|
||||
на идеях socket-активации, обычно не~требует явного описания
|
||||
зависимостей (либо требует самого минимального описания).
|
||||
Заметим, что основополагающие принципы systemd, включая
|
||||
socket-активацию, рассмотрены в статье
|
||||
\href{http://0pointer.de/blog/projects/systemd.html}{Rethinking
|
||||
PID 1}, в которой systemd был впервые представлен широкой
|
||||
публике. Ее русский перевод можно прочитать здесь:
|
||||
\href{http://tux-the-penguin.blogspot.com/2010/09/systemd.html}{часть~1},
|
||||
\href{http://tux-the-penguin.blogspot.com/2010/09/systemd-ii.html}{часть~2}.
|
||||
Возвращаясь к нашему примеру: в данном случае ценной
|
||||
информацией о зависимостях является только строка
|
||||
+Required-Start: $syslog+, сообщающая, что для работы
|
||||
abrtd требуется демон системного лога. Информация о второй
|
||||
зависимости, +$local_fs+, является избыточной, так как
|
||||
systemd приступает к запуску служб уже после того, как все
|
||||
файловые системы готовы для работы.
|
||||
\item Также, LSB-заголовок сообщает, что данная служба должна быть
|
||||
запущена на уровнях исполнения (runlevels) 3 (консольный
|
||||
многопользовательский) и 5 (графический
|
||||
многопользовательской).
|
||||
\item Исполняемый бинарник демона называется +/usr/sbin/abrtd+.
|
||||
\end{itemize}
|
||||
|
||||
Вот и вся полезная информация. Все остальное содержимое 115-строчного скрипта
|
||||
является чисто вспомогательным кодом: операции синхронизации и упорядочивания
|
||||
запуска (код, относящийся к lock-файлам), вывод информационных сообщений
|
||||
(команды +echo+), разбор входных параметров (монструозный блок
|
||||
+case+).
|
||||
|
||||
На основе приведенной выше полезной информации, мы можем написать следующий
|
||||
service-файл:
|
||||
\begin{Verbatim}
|
||||
[Unit]
|
||||
Description=Daemon to detect crashing apps
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/abrtd
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
\end{Verbatim}
|
||||
|
||||
Рассмотрим этот файл поподробнее.
|
||||
|
||||
Секция +[Unit]+ содежит самую общую информацию о службе. Не будем
|
||||
забывать, что systemd управляет не~только службами, но и многими другими
|
||||
объектами, в частности, устройствами, точками монтирования, таймерами и т.п.
|
||||
Общее наименование всех этих объектов~--- юнит (unit). Одноименная секция
|
||||
конфигурационного файла определяет наиболее общие свойства, которые могут
|
||||
быть присущи любому юниту. В нашем случае это, во-первых, строка описания, и
|
||||
во-вторых, указание, что данный юнит рекомендуется активировать после запуска
|
||||
демона системного лога\footnote{Строго говоря, эту зависимость здесь
|
||||
указывать не~нужно~--- в системах, в которых демон системного лога активируется
|
||||
через сокет, эта зависимость является избыточной. Современные реализации
|
||||
демона системного лога (например, rsyslog начиная с пятой версии)
|
||||
поддерживают активацию через сокет. В системах, использующих такие
|
||||
реализации, явное указание +After=syslog.target+ будет избыточным, так
|
||||
как соответствующая функциональность поддерживается автоматически. Однако,
|
||||
эту строчку стоит все-таки указать для обеспечения совместимости с системами,
|
||||
использующими устаревшие реализации демона системного лога}. Эта информация,
|
||||
как мы помним, была указана в LSB-заголовке исходного init-скрипта. В нашем
|
||||
конфигурационном файле мы указываем зависимость от демона системного лога при
|
||||
помощи директивы +After+, ссылающейся на юнит +syslog.taget+. Это
|
||||
специальный юнит, позволяющий ссылаться на любую реализацию демона системного
|
||||
лога, независимо от используемой программы (например, rsyslog или syslog-ng)
|
||||
и типа активации (как обычной службы или через log-сокет). Подробнее о таки
|
||||
специальных юнитах можно почитать
|
||||
\href{http://0pointer.de/public/systemd-man/systemd.special.html}{страницу}
|
||||
официальной документации. Обратите внимание, что директива +After+, в
|
||||
отсутствие директивы +Requires+, задает лишь порядок загрузки, но
|
||||
не~задает жесткой зависимости. То есть, если при загрузке конфигурация
|
||||
systemd будет предписывать запуск как демона системного лога, так и abrtd, то
|
||||
сначала будет запущен демон системного лога, и только потом abrtd. Если же
|
||||
конфигурация не~будет содержать явного указания запустить демон системного
|
||||
лога, он не~будет запущен даже при запуске abrtd. И это поведение нас
|
||||
полностью устраивает, так как abrtd прекрасно может обходиться и без демона
|
||||
системного лога. В противном случае, мы могли бы воспользоваться директивой
|
||||
+Requires+, задающей жесткую зависимость между юнитами.
|
||||
|
||||
Следующая секция, +[Service]+, содержит информацию о службе. Сюда включаются
|
||||
настройки, относящие именно к службам, но не~к другим типа юнитов. В нашем
|
||||
случае, таких настроек две: +ExecStart+ определяет расположение бинарника
|
||||
демона и аргументы, с которыми он будет вызван (в нашем случае они
|
||||
отсутствуют), и +Type+, позволяющая задать метод, по которому systemd определит
|
||||
окончание периода запуска службы. Традиционный для Unix метод демонизации
|
||||
процесса, когда исходный процесс форкается, порождая демона, после чего
|
||||
завершается, описывается типом +forking+ (как в нашем случае). Таким образом,
|
||||
systemd считает службу запущенной с момента завершения работы исходного
|
||||
процесса, и рассматривает в качестве основного процесса этой службы
|
||||
порожденный им процесс-демон.
|
||||
|
||||
И наконец, третья секция, +[Install]+. Она содержит рекомендации по
|
||||
установке конкретного юнита, указывающие, в каких ситуациях он должен быть
|
||||
активирован. В нашем случае, служба abrtd запускается при активации юнита
|
||||
+multi-user.target+. Это специальный юнит, примерно соответствующий роли
|
||||
третьего уровня исполнения классического SysV\footnote{В том контексте, в
|
||||
котором он используется в большинстве дистрибутивов семейства Red Hat, а
|
||||
именно, многопользовательский режим без запуска графической оболочки}.
|
||||
Директива +WantedBy+ никак не~влияет на уже работающую службу, но она
|
||||
играет важную роль при выполнении команды systemctl enable, задавая, в каких
|
||||
условиях должен активироваться устанавливаемый юнит. В нашем примере, служба
|
||||
abrtd будет активироваться при переходе в состояние +multi-user.target+,
|
||||
т.е., при каждой нормальной загрузке\footnote{Обратите внимание, что режим
|
||||
графической загрузки в systemd (+graphical.target+, аналог runlevel 5
|
||||
в SysV) является надстройкой над режимом многопользовательской консольной
|
||||
загрузки (+multi-user.target+, аналог runlevel 3 в SysV). Таким
|
||||
образом, все службы, запускаемые в режиме +multi-user.target+, будут
|
||||
также запускаться и в режиме +graphical.target+} (к <<ненормальным>>
|
||||
можно отнести, например, загрузки в режиме +emergency.target+, который
|
||||
является аналогом первого уровня исполнения В классической SysV).
|
||||
|
||||
Вот и все. Мы получили минимальный рабочий service-файл systemd. Чтобы
|
||||
проверить его работоспособность, скопируем его в
|
||||
+/etc/systemd/system/abrtd.service+, после чего командой
|
||||
+systemctl daemon-reload+ уведомим systemd об изменении конфигурации.
|
||||
Теперь нам остается только запустить нашу службу:
|
||||
+systemctl start abrtd.service+. Проверить состояние службы можно
|
||||
командой +systemctl status abrtd.service+, а чтобы остановить ее, нужно
|
||||
скомандовать +systemctl stop abrtd.service+. И наконец, команда
|
||||
+systemctl enable abrtd.service+ выполнит установку service-файла,
|
||||
обеспечив его активацию при каждой загрузке (аналог +chkconfig abrtd on+
|
||||
в классическом SysV).
|
||||
|
||||
Приведенный выше service-файл является практический точным переводом
|
||||
исходного init-скрипта, и он никак не~использует широкий спектр возможностей,
|
||||
предоставляемых systemd. Ниже приведен немного улучшенный вариант:
|
||||
|
||||
\begin{Verbatim}
|
||||
[Unit]
|
||||
Description=ABRT Automated Bug Reporting Tool
|
||||
After=syslog.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=com.redhat.abrt
|
||||
ExecStart=/usr/sbin/abrtd -d -s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
\end{Verbatim}
|
||||
|
||||
Чем же новый вариант отличается от предыдущего? Ну, прежде всего, мы уточнили
|
||||
описание службы. Однако, ключевым изменением является замена +Type+ с +forking+
|
||||
на +dbus+ и связанные с ней изменения: добавление имени службы в шине D-Bus
|
||||
(директива +BusName+) и задание полонительных аргументов abrtd <<+-d -s+>>. Но
|
||||
зачем вообще нужна эта замена? Каков ее практический смысл? Чтобы ответить на
|
||||
этот вопрос, мы снова возращаемся к демонизации. В ходе этой операции, процесс
|
||||
дважды форкается и отключается от всех терминалов. Это очень удобно при запуске
|
||||
демона через скрипт, но в случае использования таких продвинутых систем
|
||||
инициализации, как systemd, такое поведение не~дает никаких преимуществ, но
|
||||
вызывает неоправданные задержки. Даже если мы оставим в стороне вопрос скорости
|
||||
загрузки, останется такой важный аспект, как отслеживание состояния служб.
|
||||
systemd решает и эту задачу, контролируя работу службы и при необходимости
|
||||
реагируя на различные события. Например, при неожиданном падении основного
|
||||
процесса службы, systemd должен зарегистрировать идентификатор и код выхода
|
||||
процесса, также, в зависимости от настроек, он может попытаться перезапустить
|
||||
службу, либо активировать какой-либо заранее заданный юнит. Операция
|
||||
демонизации несколько затрудняет решение этих задач, так как обычно довольно
|
||||
сложно найти связь демонизированного процесса с исходным (собственно, смысл
|
||||
демонизации как раз и сводится к уничтожению этой связи) и, сооветственно, для
|
||||
systemd сложнее определить, какой из порожденных в рамках данной службы
|
||||
процессов является основным. Чтобы упростить для него решение этой задачи, мы и
|
||||
воспользовались типом запуска +dbus+. Он подходит для всех служб, которые в
|
||||
конце процесса инициализации регистрируют свое имя на шине D-Bus\footnote{В
|
||||
настоящее время практически все службы дистрибутива Fedora после запуска
|
||||
регистрируется на шине D-Bus}. ABRTd относится к ним. С новыми настройками,
|
||||
systemd запусит процесс abrtd, который уже не~будет форкаться (согласно
|
||||
указанным нами ключам <<+-d -s+>>), и в качестве момента окончания периода
|
||||
запуска данной службы systemd будет рассматривать момент регистрации имени
|
||||
+com.redhat.abrt+ на шине D-Bus. В этом случае основным для данной службы будет
|
||||
считаться процесс, непосредственно порожденный systemd. Таким образом, systemd
|
||||
располагает удобным методом для определения момента окончания запуска службы, а
|
||||
также может легко отслеживать ее состояние.
|
||||
|
||||
Собственно, это все, что нужно было сделать. Мы получили простой
|
||||
конфигурационный файл, в 10 строчках которого содержится больше полезной
|
||||
информации, чем в 115 строках исходного init-скрипта. Добавляя в наш файл по
|
||||
одной строчке, мы можем использовать различные полезные функции systemd,
|
||||
создание аналога которых в традиционном init-скрипте потребовало бы
|
||||
значительных усилий. Например, добавив строку +Restart=restart-always+, мы
|
||||
приказываем systemd автоматически перезапускать службу после каждого ее
|
||||
падения. Или, например, добавив +OOMScoreAdjust=-500+, мы попросим ядро сберечь
|
||||
эту службу, даже если OOM Killer выйдет на тропу войны. А если мы добавим
|
||||
строчку +CPUSchedulingPolicy=idle+, процесс abrtd будет работать только в те
|
||||
моменты, когда система больше ничем не~занята, что позволит не создавать помех
|
||||
для процессов, активно использующих CPU.
|
||||
|
||||
За более подробным описанием всех опций настройки, вы можете обратиться к
|
||||
страницам рукводства
|
||||
\href{http://0pointer.de/public/systemd-man/systemd.unit.html}{systemd.unit},
|
||||
\href{http://0pointer.de/public/systemd-man/systemd.service.html}{systemd.service},
|
||||
\href{http://0pointer.de/public/systemd-man/systemd.exec.html}{systemd.exec}. Полный
|
||||
список доступных страниц можно просмотреть
|
||||
\href{http://0pointer.de/public/systemd-man/}{здесь}.
|
||||
|
||||
Конечно, отнюдь не~все init-скрипты так же легко преобразовать в
|
||||
service-файлы. Но, к счастью, <<проблемных>> скриптов не~так уж и много.
|
||||
|
||||
\section{Убить демона}
|
||||
|
||||
Убить системного демона нетрудно, правда? Или\ldots все не~так просто?
|
||||
|
||||
Если ваш демон функционирует как один процесс, все действительно очень просто.
|
||||
Вы командуете +killall rsyslogd+, и демон системного лога останавливается.
|
||||
Впрочем, этот метод не~вполне корректен, так как он действует не~только на
|
||||
самого демона, но и на другие процессы с тем же именем. Иногда подобное
|
||||
поведение может привести к неприятным последствиям. Более правильным будет
|
||||
использование pid-файла: +kill \$(cat /var/run/syslogd.pid)+. Вот, вроде
|
||||
бы, и все, что вам нужно\ldots Или мы упускаем еще что-то?
|
||||
|
||||
Действительно, мы забываем про одну простую вещь: существуют службы, такие, как
|
||||
Apache, crond, atd, которые по роду служебной дейятельности должны запускать
|
||||
дочерние процессы. Это могут быть совершенно посторонние, указаанные
|
||||
пользователем программы (например, задачи cron/at, CGI-скрипты) или полноценные
|
||||
серверные процессы (например, Apache workers). Когда вы убиваете основной
|
||||
процесс, он может остановить все дочерние процессы. А может и не~остановить. В
|
||||
самом деле, если служба функционирует в штатном режиме, ее обычно останавливают
|
||||
специальной командой stop. К прямому вызову kill администратор, как правило,
|
||||
прибегает только в аварийной ситуации, когда служба работает неправильно и
|
||||
может не~среагировать на стандартную команду остановки. Таким образом, убив,
|
||||
например, основной сервер Apache, вы можете получить от него в наследство
|
||||
работающие CGI-скрипты, причем их родителем автоматически станет PID 1 (init),
|
||||
так что установить их происхождение будет не~так-то просто.
|
||||
|
||||
\href{http://www.freedesktop.org/wiki/Software/systemd}{systemd} спешит к нам
|
||||
на помощь. Команда +systemctl kill+ позволит отправить сигнал всем
|
||||
процессам, порожденным в рамках данной службы. Например:
|
||||
|
||||
\begin{Verbatim}
|
||||
# systemctl kill crond.service
|
||||
\end{Verbatim}
|
||||
|
||||
Вы можете быть уверены, что всем процессам службы cron будет отправлен сигнал
|
||||
+SIGTERM+. Разумеется, можно отправить и любой другой сигнал. Скажем, если ваши
|
||||
дела совсем уж плохи, вы можете воспользоваться и +SIGKILL+:
|
||||
|
||||
\begin{Verbatim}
|
||||
# systemctl kill -s SIGKILL crond.service
|
||||
\end{Verbatim}
|
||||
|
||||
После ввода этой команды, служба cron будет жестоко убита вместе со всеми ее
|
||||
дочерними процессами, вне зависимости от того, сколько раз она форкалась, и
|
||||
как бы она ни пыталась сбежать из-под нашего контроля при помощи двойного
|
||||
форка или
|
||||
\href{http://ru.wikipedia.org/wiki/Fork-%D0%B1%D0%BE%D0%BC%D0%B1%D0%B0}{форк-бомбардировки}%
|
||||
\footnote{Прим. перев.: стоит особо отметить, что использование контрольных
|
||||
групп не~только упрощает процесс уничтожения форк-бомб, но и значительно
|
||||
уменьшает ущерб от работающей форк-бомбы. Так как systemd автоматически
|
||||
помещает каждую службу и каждый пользовательский сеанс в свою контрольную
|
||||
группу по ресурсу процессорного времени, запуск форк-бомбы одним
|
||||
пользователем или службой не~создаст значительных проблем с отзывчивостью
|
||||
системы у других пользователей и служб. Таким образом, в качестве основной
|
||||
угрозы форк-бомбардировки остаются лишь возможности исчерпания памяти и
|
||||
идентификаторов процессов (PID)}.
|
||||
|
||||
В некоторый случах возникает необходимость отправить сигнал именно основному
|
||||
процессу службы. Например, используя +SIGHUP+, мы можем заставить демона
|
||||
перечитать файлы конфигурации. Разумеется, вспомогательным процессам
|
||||
передавать HUP в этом случае совершенно необязательно. Для решения этой
|
||||
задачи вполbb неплохо подойдет и классический метод с pid-файлом, однако у
|
||||
systemd и на этот случай есть просто решение, избавляющее вас от
|
||||
необходимости искать нужный файл:
|
||||
|
||||
\begin{Verbatim}
|
||||
# systemctl kill -s HUP --kill-who=main crond.service
|
||||
\end{Verbatim}
|
||||
|
||||
Итак, что же принципиально новое привносит systemd в рутинный процесс
|
||||
убийства демона? Прежде всего: впервые в истории Linux представлен способ
|
||||
принудительной остановки службы, не~зависящий от того, насколько
|
||||
добросовестно основной процесс службы выполняет свои обязательства по
|
||||
остановке дочерних процессов. Как уже упоминалось выше, необходимость
|
||||
отправить процессу +SIGTERM+ или +SIGKILL+ обычно возникает именно
|
||||
в нештатной ситуации, когда вы уже не~можете быть уверены, что демон
|
||||
корректно исполнит все свои обязанности.
|
||||
|
||||
После прочтения сказанного выше у вас может возникнуть вопрос: в чем разница
|
||||
между +systemctl kill+ и +systemctl stop+? Отличие состоит в том,
|
||||
что +kill+ просто отправляет сигнал заданному процессу, в то время как
|
||||
stop действует по <<официально>> определенному методу, вызывая команду,
|
||||
определенную в параметре +ExecStop+ конфигурации службы. Обычно команды
|
||||
stop бывает вполне достаточно для остановки службы, и к +kill+
|
||||
приходится прибегать только в крайних случаях, например, когда служба
|
||||
<<зависла>> и не~реагирует на команды.
|
||||
|
||||
Кстати говоря, при использовании параметра <<+-s+>>, вы можете указывать
|
||||
названия сигналов как с префиксом SIG, так и без него~--- оба варианта будут
|
||||
работать.
|
||||
|
||||
В завершение стоит сказать, что для нас весьма интересным и неожиданным
|
||||
оказался тот факт, что до появления systemd в Linux просто не~существовало
|
||||
инструментов, позволяющих корректно отправить сигнал службе в целом, а
|
||||
не~отдельному процессу.
|
||||
|
||||
\end{document}
|
||||
Reference in New Issue
Block a user