commit 9e01b104e42b446ac88ed01e53a8c7506a6ad3ab Author: nnz1024 <0comffdiz@inbox.ru> Date: Tue Dec 28 11:43:00 2010 +0300 Version v1.0 (2010-12-28 11:43) [AUTO] diff --git a/s4a.tex b/s4a.tex new file mode 100644 index 0000000..eec8c87 --- /dev/null +++ b/s4a.tex @@ -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 Строка описания службы: <>. Как + нетрудно заметить, комментарии в заголовке скрипта весьма + пространны и описывают не~сколько саму службу, сколько + скрипт, ее запускающий. 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}