SYSTEMD.SERVICE(5) systemd.service SYSTEMD.SERVICE(5)

НАЗВА

systemd.service — налаштування модуля служби

КОРОТКИЙ ОПИС

служба.service

ОПИС

У файлі налаштувань модуля, назва якого завершується суфіксом «.service», закодовано відомості щодо процесу, керування і нагляд за яким здійснює systemd.

На цій сторінці підручника наведено список параметрів налаштувань, які є специфічними для цього типу модулів. Див. systemd.unit(5), щоб дізнатися більше про загальні параметри усіх файлів налаштувань модулів. Загальні пункти налаштувань визначаються у типових розділах [Unit] і [Install]. Специфічні для служби параметри налаштувань визначаються у розділі [Service].

Список додаткових параметрів наведено на сторінці підручника з systemd.exec(5), програми, яка визначає середовище виконання команд, systemd.kill(5), програми, яка визначає спосіб, у який переривається робота процесів служби, та systemd.resource-control(5), програми, яка налаштовує параметри керування ресурсами для процесів служби.

Якщо увімкнено сумісність із SysV init, systemd автоматично створює модулі, які включають скрипти ініціалізації SysV (назва служби збігатиметься із назвою скрипту, суфіксом буде «.service»); див. systemd-sysv-generator(8).

Команда systemd-run(1) уможливлює створення модулів .service і .scope динамічно і інтерактивно з командного рядка.

ШАБЛОНИ СЛУЖБ

Служби systemd можуть приймати одинарний аргумент, який передають синтаксичною конструкцією «служба@аргумент.service». Такі служби називають «реалізованими», а визначення модулів без параметра аргумент називають «шаблоном». Прикладом може бути шаблон служби dhcpcd@.service, який приймає назву інтерфейсу мережі яка параметр при формуванні реалізованої служби. У файлі служби доступ до цього параметра або «назви екземпляра» можна отримати за допомогою %-специфікаторів. Див. systemd.unit(5), щоб дізнатися більше.

АВТОМАТИЧНІ ЗАЛЕЖНОСТІ

Неявні залежності

Неявним чином додано такі залежності:

•Служби із автоматичним встановленням Type=dbus надсилають запит щодо залежностей типу Requires= і After= до dbus.socket.
•Активовані через сокет служби автоматично упорядковуються після активації модулів .socket за допомогою автоматичної залежності After=. Служби також викликають усі модулі .socket зі списку у Sockets= за допомогою автоматичних залежностей Wants= і After=.

Додаткові неявні залежності можна додавати як результат параметри керування виконанням і ресурсами, як це документовано на сторінках підручника щодо systemd.exec(5) і systemd.resource-control(5).

Типові залежності

Буде додано такі залежності, якщо не встановлено DefaultDependencies=no:

•Модулі служб матиму залежності типу Requires= і After= від sysinit.target, залежність типу After= від basic.target, а також залежності типу Conflicts= і Before= від shutdown.target. Таким чином забезпечено те, що звичайні модулі служб включають базову ініціалізацію системи, і штатно припиняють роботу перед вимиканням системи. Вимикати цей параметр слід лише для служб, які використовують на ранньому етапі завантаження або на пізньому етапі вимикання системи.
•Реалізовані модулі служб (тобто модулі служб із «@» у назвах) типово пов'язано із модулем зрізу окремого шаблона (див. systemd.slice(5)), який названо за модулем шаблона, у якому містяться усі екземпляри певного шаблона. Цей зріз зазвичай буде зупинено під час завершення роботи системи разом із усіма екземплярами шаблонів. Якщо така поведінка є небажаною, встановіть DefaultDependencies=no у модулі шаблона, і або визначте ваш власний файл модуля зрізу окремого шаблона, який також встановлює DefaultDependencies=no, або встановіть Slice=system.slice (або інший відповідний зріз) у модулі шаблона. Див. також systemd.resource-control(5).

ПАРАМЕТРИ

Файли модулів служб можуть включати розділи [Unit] і [Install], які описано на сторінці підручника щодо systemd.unit(5).

Файли модулів служб мають включати розділ [Service], який містить відомості щодо служби і процесу, за яким вона наглядає. Численні параметри, які може буде використано у цьому розділі, є спільними із іншими типами модулів. Ці параметри документовано на сторінках підручника щодо systemd.exec(5), systemd.kill(5) і systemd.resource-control(5). Параметрами, які є специфічними для розділу [Service] модулів служб, є такими:

Type=

Налаштовує механізм, за допомогою якого служба сповіщає засіб керування про те, що запуск служби завершено. Одне зі значень simple, exec, forking, oneshot, dbus, notify, notify-reload або idle:
•Якщо встановлено значення simple (типово, якщо вказано ExecStart=, але не вказано ні Type=, ні BusName=), при керуванні службами вважатиметься, що модуль запущено одразу після відгалуження процесу основної служби (тобто негайно після fork() і перед різними налаштованими атрибутами процесу і, зокрема, перед тим, як новий процес викликав execve() для запуску справжнього виконуваного файла служби). Типово, кращим вибором є Type=exec (див. нижче).

Очікується, що процес, який налаштовано за допомогою ExecStart= є основним процесом служби. У цьому режимі, якщо процес надає функціональні можливості іншим процесам у системі, його канали обміну даними має бути встановлено до запуску служби (наприклад, сокети має бути налаштовано systemd за допомогою активації сокетів), оскільки засіб керування службами негайно продовжить запуск наступних модулів, одразу після створення процесу основної служби і до виконання виконуваного файла служби. Зауважте, що це означає, що рядки команд systemctl start для служб simple повідомлятимуть про успіх, навіть якщо виконуваний файл служби не вдасться викликати успішно (наприклад, оскільки вибраного користувача User= не існує або не буде знайдено виконуваного файла служби).

•Тип exec подібний до типу simple, але засіб керування службами намагатиметься запустити модуль одразу після виконання виконуваного файла основної служби. Засіб керування службами затримає запуск наступних модулів, аж до цієї події. (Іншими словами: simple продовжує роботу з наступними завданнями одразу після повернення з функції fork(), а exec не продовжуватиме обробку, доки не буде успішно виконано як fork(), так і execve() у процесі служби.) Зауважте, що це означає, що рядки команд systemctl start для служб exec повертатимуть помилку, якщо не вдасться успішно викликати виконуваний файл служби (наприклад, через те, що вибраного за допомогою User= облікового запису користувача не існує або не буде знайдено виконуваного файла служби).
•Якщо встановлено значення forking, при керуванні службами вважатиметься, що модуль запущено одразу після завершення роботи виконуваного файла, який було відгалужено засобом керування Не варто користуватися цим типом — скористайтеся замість нього dbus .

Процес, який налаштовано за допомогою ExecStart=, має викликати fork(), як частину свого запуску. Батьківський процес має завершити роботу при завершенні запуску, а усі канали обміну даними має бути налаштовано. Дочірній процес продовжуватиме працювати як основний процес служби, а засіб керування службами вважатиме модуль запущеним, коли батьківський процес завершить роботу. Це поведінка традиційних служб UNIX. Якщо використано цей параметр, рекомендуємо також скористатися параметром PIDFile=, щоб systemd можна було надійно ідентифікувати основний процес служби. Засіб керування продовжить запускати наступні модулі, після завершення роботи батьківського процесу.

•Поведінка у варіанті з oneshot подібна до simple. Втім, засіб керування службами вважатиме модуль запущеним після завершення роботи основного процесу. Далі, він запустить наступні модулі. Для цього типу служб корисним є зокрема встановлення RemainAfterExit=. Type=oneshot є типовим неявним варіантом, якщо не встановлено ні Type=, ні ExecStart=. Зауважте, що якщо використано цей варіант без RemainAfterExit=, служба ніколи не увійде до стану модуля «active», а безпосередньо перейде зі стану «activating» до стану «deactivating» або «dead», оскільки не налаштовано процесу, який має працювати неперервно. Це, зокрема, означає, що після запуску служби цього типу (для якої не встановлено RemainAfterExit=) вона не потрапить до списку запущених, а лише до списку «мертвих».
•Поведінка для dbus є подібною до поведінки для simple; втім, для модулів цього типу слід вказати BusName=, а керування службами вважатиме модуль запущеним, якщо було отримано вказану назву шини. Цей тип є стандартним, якщо вказано BusName=.

Модулі служб, якщо вказано цей варіант, неявно отримуватимуть залежності від модуля dbus.socket. Модуль служби цього типу вважається таким, що перебуває в активному стані, аж доки не буде отримано вказаної назви каналу. Він вважається активованим, доки чинною є отримана назва каналу. Щойно назву каналу буде вивільнено, служба вважається нефункціональною, що спричиняє те, що засіб керування службами спробує перервати будь-які залишкові процеси, що належать службі. Через це, служби, які скидають назву каналу у процесі логіки завершення своєї роботи, слід приготувати до отримання SIGTERM (або будь-якого іншого сигналу, який налаштовано у KillSignal=).

•Поведінка у варіанті notify є подібною до exec. Втім, служба має надіслати повідомлення-сповіщення «READY=1» за допомогою sd_notify(3) або еквівалентного виклику під час завершення запуску. systemd продовжить запуском наступних модулів після надсилання цього повідомлення-сповіщення. Якщо використано цей варіант, має бути встановлено значення NotifyAccess= (див. нижче) для відкриття доступу до сокета сповіщення, який надається systemd. Якщо NotifyAccess= не вказано або встановлено у значення none, для нього примусово буде встановлено значення main.

Якщо для служби передбачено підтримку перезавантаження, і вона використовує сигнал для запуску перезавантаження, рекомендуємо замість цього варіанта скористатися notify-reload.

•Поведінка notify-reload є тотожною до notify. Втім, тут логіку розширено: сигнал SIGHUP процесу UNIX буде надіслано до основного процесу служби, коли служба проситиме про перезавантаження, а керування службами чекатиме на сповіщення щодо завершення перезавантаження.

При започаткуванні процесу перезавантаження від служби очікують відповіді з повідомленням-сповіщенням через sd_notify(3). У повідомленні має міститися поле «RELOADING=1» у поєднанні і встановленням «MONOTONIC_USEC=» у значення поточного монотонного часу (тобто CLOCK_MONOTONIC у clock_gettime(2)) у мкс, форматованого у десятковий рядок. Щойно перезавантаження буде завершено, має бути надіслано ще одне повідомлення-сповіщення, що містить «READY=1». Використання цього типу служби і реалізація цього протоколу перезавантаження є ефективною альтернативою використанню команди ExecReload= для перезавантаження налаштувань служби.

Надісланий сигнал можна скоригувати за допомогою ReloadSignal=, див. нижче.

•Поведінка у варіанті idle є дуже подібною до simple. Втім, справжнє виконання програми служби буде відкладено до того, як буде розподілено усі активні завдання. Цим можна скористатися для уникнення змішування виведення служб оболонки із виведенням стану до консолі. Зауважте, що цей тип корисний лише для удосконалення виведення до консолі, він не придатний як загальний інструмент упорядковування модулів, а вплив цього типу служб обмежено п'ятисекундним часом очікування, після якого службову програму буде викликано попри усе.

Рекомендуємо користуватися Type=notify для служб, які працюють довго, оскільки так можна буде належним чином стежити за помилками у налаштовування процесів (наприклад помилками, подібними до неможливості знайти виконуваний файл служби або невказаного користувача). Втім, оскільки для цього типу служби критичні помилки у власному коді запуску служби не поширюються (на відміну від критичних помилок на кроках приготування, які засіб керування службами виконує до execve()), і він не дозволяє упорядковування інших модулів за результатами завершення ініціалізації самого коду служби (що, наприклад, є корисним, якщо клієнти потребують з'єднання із службою за допомогою певної форми IPC, а канал IPC буде встановлено самою службою, на відміну від виконання цього завдання наперед за допомогою сокета, активації каналу або подібної дії), його може бути недостатньо у багатьох випадках. Якщо це так, notify, notify-reload або dbus (останній лише у випадку, якщо служба надає інтерфейс D-Bus) є пріоритетнішими варіантами, оскільки вони уможливлюють для коду програм служб точне планування того, коли слід вважати запуск служби успішним, і коли слід слід продовжити обробку наступних модулів. Типи служби notify/notify-reload потребують явної підтримки у коді служби (оскільки службі доведеться у відповідний момент викликати sd_notify() або еквівалентний програмний інтерфейс) — якщо її підтримки не передбачено, альтернативою є forking: у цьому варіанті передбачено підтримку традиційного важкого протоколу запуску служб UNIX. Зауважте, що використання будь-якого типу, відмінного від simple, ймовірно, затримає процес завантаження системи, оскільки засобу керування системою доведеться чекати на завершення ініціалізації принаймні якоїсь служби. (Також зауважте, що, загалом, не рекомендовано користуватися idle або oneshot для служб, які працюватимуть довго.)

Зауважте, що різні параметри служб (наприклад User=, Group= через libc NSS) можуть призводити до «прихованого» блокування викликів IPC для інших служб. Іноді варто скористатися типом служби simple для забезпечення того, що на логіку обміну даними засобу керування службами не вплинуть такі потенційно повільні дії та приховані залежності, оскільки це єдиний тип служби, за якого засіб керування службами не чекатиме на завершення таких дій з налаштовування запуску служб, перш ніж продовжувати роботу.

ExitType=

Вказує, коли засіб керування може вважати службу завершеною. Значення — main або cgroup:
•Якщо встановлено значення main (типовий варіант), засіб керування службами вважатиме модуль зупиненим, якщо основний процес, який визначено відповідно до Type=, завершить роботу. Отже, його не можна використовувати у поєднанні із Type=oneshot.
•Якщо встановлено значення cgroup, служба вважатиметься запущено, якщо існує принаймні один процес у cgroup, який не завершив роботу.

Загалом, рекомендовано використовувати ExitType=main, якщо служба має відому модель відгалуження і основний процес може бути надійно визначено. Варіант ExitType= cgroup призначено для програм, чия модель відгалуження є наперед невідомою і які можуть не мати певного основного процесу. Його добре пристосовано для тимчасових або автоматично створених служб, зокрема графічних програм у стільничному середовищі.

RemainAfterExit=

Приймає булеве значення, яке визначає, чи слід вважати службу активною, навіть якщо усі її процеси завершили роботу. Типовий значенням є no («ні»).

GuessMainPID=

Приймає булеве значення, яке визначає, чи має systemd намагатися визначити основний PID служби, якщо його не вдасться надійно визначити. Цей параметр буде проігноровано, якщо не встановлено Type=forking і не встановлено PIDFile=, оскільки для інших типів або при явним чином налаштованому файлі PID, основний PID буде завжди відомим. Алгоритм визначення може призвести до помилкових результатів, якщо фонова служба складається з декількох процесів. Якщо основний PID не може бути визначено, виявлення помилок і автоматичний перезапуск служби не працюватиме надійним чином. Типовим значенням є yes.

PIDFile=

Приймає шлях, що посилається на файл PID служби. Цей параметр рекомендовано використовувати для служб, для яких Type= встановлено у значення forking. Заданий шлях, типово, вказує на файл у каталозі /run/. Отже, якщо вказано відносний шлях, до нього буде дописано префікс /run/. Засіб керування службами прочитає PID основного процесу служби з цього файла після запуску служби. Засіб керування службами не записуватиме даних до налаштованого цим параметром файла, хоча він і вилучить файл після того, як роботу служби буде завершено, якщо цей файл ще існуватиме. Власником файла PID не обов'язково має бути привілейований користувач, але якщо він належатиме непривілейованому користувачу, буде вжито додаткові заходи безпеки: файл не зможе бути символічним посиланням на файл, власником якого є інший користувач (безпосередньо або опосередковано), і файл PID має посилатися на процес, який вже належить службі.

Зауважте, що у сучасних проєктах слід уникати файлів PID. Де це можливо, використовуйте Type=notify, Type=notify-reload або Type=simple, типи, які не вимагають використання файлів PID для визначення основного процесу служби, і не потребують зайвого відгалуження.

BusName=

Приймає назву призначення D-Bus, яку має використовувати ця служба. Цей параметр є обов'язковим для служб, де для Type= встановлено значення dbus. Рекомендуємо завжди встановлювати цю властивість, якщо вона відома, щоб спростити прив'язку назви служби до призначення D-Bus. Зокрема, цими прив'язками користуються команди systemctl service-log-level/service-log-target.

ExecStart=

Команди, які буде виконано при запуску цієї служби. Це значення буде поділено на нуль або більшу кількість рядків команд, відповідно до правил, які описано у розділі «РЯДКИ КОМАНД» нижче.

Якщо для Type= не встановлено значення oneshot, має бути задано точно одну команду. Якщо використано Type=oneshot, може бути вказано нуль або більшу кількість команд. Команди можна вказати заданням декількох рядків команд у одній інструкції або, інакше, цей параметр можна вказати декілька разів з тими самими наслідками. Якщо цьому параметру надано порожнє значення, список команд, які слід запустити, буде скинуто, попередні надання значень цьому параметру втратять чинність. Якщо значення ExecStart= не вказано, служба повинна мати RemainAfterExit=yes і принаймні один встановлений рядок ExecStop=. (Служби, для яких не вказано обох, ExecStart= і ExecStop=, не є чинними.)

Якщо вказано декілька команд, команди буде викликано послідовно у тому порядку, у якому їх вказано у файлі модуля. Якщо виконання однієї з команд завершиться помилкою (і для неї не вказано префікса «-»), інші рядки не буде виконано, а модуль вважатиметься таким, виконання якого завершилося помилкою.

Якщо не встановлено Type=forking, процес, який запущено за допомогою цього рядка команди, буде вважатися основним процесом фонової служби.

ExecStartPre=, ExecStartPost=

Додаткові команди, які буде виконано до або після команди ExecStart=, відповідно. Синтаксис є таким самим, як і для ExecStart=, окрім того, що можна використовувати декілька рядків команд, а команди буде виконано одна за одною, послідовно.

Якщо виконання будь-якої з цих команд (у якої немає префікса «-») завершиться помилкою, решту команд не буде виконано, а виконання модуля вважатиметься таким, що завершилося помилкою.

Команди ExecStart= буде виконано лише після того, як виконання усіх команд ExecStartPre=, до яких не було додано префікса «-», буде успішно завершено.

Команди ExecStartPost= буде запущено лише після успішного виклику команд, які вказано в ExecStart=, якщо це визначено Type= (тобто запуску процесу для Type=simple, або успішного завершення останнього процесу ExecStart= для Type=oneshot, успішного завершення початкового процесу для Type=forking, надсилання «READY=1» для Type=notify/Type=notify-reload, або отримання BusName= для Type=dbus).

Зауважте, що ExecStartPre= не можна використовувати для запуску довготривалих процесів. Усі процеси, які відгалужено процесами, які викликано за допомогою ExecStartPre=, буде завершено примусово до того, як буде запущено наступний процес служби.

Зауважте, що якщо будь-яка з цих команд, вказаних у ExecStartPre=, ExecStart= або ExecStartPost=, завершить роботу критичною помилкою (і для неї не буде вказано префікса «-», див. вище) або перевищить час очікування на дані до повного запуску служби, буде продовжено виконання команд, які вказано у ExecStopPost=. Команди в ExecStop= буде пропущено.

Зауважте, що виконання ExecStartPost= буде взято до уваги для упорядковувальних обмежень Before=/After=.

ExecCondition=

Необов'язкові команди, які буде виконано до команди ExecStartPre=, відповідно Синтаксис є таким самим, як і для ExecStart=, окрім того, що можна використовувати декілька рядків команд, а команди буде виконано одна за одною, послідовно.

Поведінка буде подібною до ExecStartPre= і гібриду перевірки умов: якщо команда ExecCondition= завершить роботу із кодом виходу від 1 до 254 (включно), решту команд буде пропущено, а модуль не буде позначено як такий, виконання якого завершилося помилкою. Втім, якщо команда ExecCondition= завершить роботу зі станом виходу 255 або у критичному режимі (тобто через перевищення часу очікування, переривання сигналом тощо), модуль вважатиметься таким, виконання якого завершилося помилкою (і решту команд буде пропущено). Якщо кодом виходу буде 0 або код із SuccessExitStatus=, буде продовжено виконання наступних команд.

Ті самі рекомендації щодо того, що не слід запускати довготривалі процеси в ExecStartPre=, стосуються і ExecCondition=. ExecCondition= також запускатиме команди в ExecStopPost=, як частину процедури зупинення роботи служби у випадку будь-яких ненульових або нештатних виходів, подібних до тих, які описано вище.

ExecReload=

Команди, які слід виконати для ініціалізації перезавантаження налаштувань служби. Цей аргумент приймає декілька рядків команд за тією самою схемою, яку описано для ExecStart= вище. Використання цього параметра є необов'язковим. Тут передбачено підтримку заміни специфікаторів та змінних середовища за тією самою схемою, що і для ExecStart=.

Буде встановлено одну додаткову спеціальну змінну середовища: буде встановлено $MAINPID у значення, якщо воно відоме, назви основного процесу фонової служби, і цією змінною можна буде скористатися у рядках команд, подібних до такого:

ExecReload=kill -HUP $MAINPID

Втім, зауважте, що перезавантаження фонової служби надсиланням до черги обробки сигналу (як і з прикладом рядка вище), зазвичай, не дуже вдалий вибір, оскільки це асинхронна дія, яка є непридатною для упорядкованого перезавантаження одразу декількох служб. Наполегливо рекомендуємо або скористатися Type=notify-reload замість ExecReload=, або встановити для ExecReload= значення команди, яка не лише ініціює перезавантаження налаштувань фонової служби, але також синхронно очікує на його завершення. Наприклад, dbus-broker(1) використовує таке:

ExecReload=busctl call org.freedesktop.DBus \
        /org/freedesktop/DBus org.freedesktop.DBus \
        ReloadConfig

ExecStop=

Команди, які слід виконати для зупинення служби, яку запущено за допомогою ExecStart=. Цей аргумент приймає декілька рядків команд у тій самій схемі, яку описано для ExecStart= вище. Цей параметр є необов'язковим. Після того, як буде запущено команди, які налаштовано цим параметром, припускається, що роботу служби зупинено, і усі залишкові процеси для неї буде перервано, відповідно до параметра KillMode= (див. systemd.kill(5)). Якщо цей параметр не вказано, процес буде перервано надсиланням сигналу, який вказано за допомогою KillSignal= або RestartKillSignal=, коли надіслано запит щодо зупинення служби. Передбачено підтримку заміни специфікаторів та змінних середовища (зокрема $MAINPID, див. вище).

Зауважте, що, зазвичай, для цього параметра недостатньо вказати команду, якщо лише попросить службу припинити роботу (наприклад, надсиланням у певній формі сигналу щодо переривання), але не очікує на завершення припинення роботи. Оскільки роботу решти процесів служби буде припинено відповідно до KillMode= і KillSignal= або RestartKillSignal=, як це описано вище, негайно після завершення роботи команди, зупинення роботи може статися нештатно. Отже, вказана команда має бути синхронною, а не асинхронною дією.

Зауважте, що команди, вказані в ExecStop=, буде виконано, лише коли спочатку запущено службу. Їх не буде викликано, якщо службу не було взагалі запущено або якщо спроба запуску завершилася помилкою, наприклад, оскільки спроба виконання якоїсь із команд, які вказано в ExecStart=, ExecStartPre= або ExecStartPost=, завершилося помилкою (і до команди не було дописано префікс «-», див. вище) або було перевищено час очікування на дані. Скористайтеся ExecStopPost= для виклику команд, якщо служба не може запуститися належним чином і завершує роботу знову. Також зауважте, що дію з зупинення завжди буде виконано, якщо службу успішно запущено, навіть якщо процеси у службі перервано самим процесом або ззовні. Команди зупинення має бути приготовано для роботи у цьому випадку. Встановлення значення $MAINPID буде скасовано, якщо systemd стане відомо, що основний процес завершив роботу на момент виклику команд зупинення.

Запити щодо перезапуску служби реалізовано як дії з зупинення, за якими слідують дії із запуску. Це означає, що ExecStop= і ExecStopPost= буде виконано під час дії із перезапуску служби.

Рекомендуємо скористатися цим параметром для команд, які обмінюються даними зі службою, яка потребує штатного переривання роботи. Для кроків чищення після завершення роботи скористайтеся замість цього параметра параметром ExecStopPost=.

ExecStopPost=

Додаткові команди, які буде виконано після зупинення служби. Це стосується випадків, коли було використано команди, які налаштовано у ExecStop=, де для служби не визначено якихось ExecStop=, або служб, які завершили роботу нештатно. Цей аргумент приймає декілька рядків команд за тією самою схемою, яку описано для ExecStart=. Використання цих параметрів є необов'язковим. Передбачено підтримку заміни специфікаторів та змінних середовища. Зауважте, що — на відміну від ExecStop= — команди, які вказано за допомогою цього параметра, буде викликано, коли службу не вдасться запустити належним чином і її роботу знову буде завершено.

Рекомендуємо скористатися цим параметром для дій з чищення, які буде виконано, навіть якщо службу не вдасться запустити належним чином. Команди, які налаштовано за допомогою цього параметра повинні діяти, навіть якщо запуск служби завершився невдачею десь на проміжному етапі і лишив десь неповністю ініціалізовані дані. Оскільки процеси служби вже перервали роботу на момент виконання команд, які задано цим параметром, команди не повинні обмінюватися даними із процесами служби.

Зауважте, що усі команди, які налаштовано за допомогою цього параметра, буде викликано із кодом результату служби, а також кодом виходу і стану основного процесу, які встановлено у змінних середовища $SERVICE_RESULT, $EXIT_CODE і $EXIT_STATUS. Див. systemd.exec(5), щоб дізнатися більше.

Зауважте, що виконання ExecStopPost= буде взято до уваги для упорядковувальних обмежень Before=/After=.

RestartSec=

Налаштовує час присипляння до перезапуску служби (як налаштовано за допомогою Restart=). Приймає безрозмірне значення у секундах або значення проміжку часу, подібне до «5min 20s». Типовим значенням є 100 мс.

RestartSteps=

Налаштовує кількість кроків, які слід виконати при нарощуванні проміжку автоматичного перезапуску від RestartSec= до RestartMaxDelaySec=. Приймає додатне ціле число або 0 для вимикання можливості. Типовим значенням є 0.

Цей параметр працюватиме, лише якщо також встановлено RestartMaxDelaySec=.

RestartMaxDelaySec=

Налаштовує найдовший час присипляння до перезапуску служби як проміжок часу від RestartSteps=. Приймає значення у тому самому форматі, що і RestartSec=, або «infinity» для вимикання. Типовим значенням є «infinity».

Цей параметр працюватиме, лише якщо також встановлено RestartSteps=.

TimeoutStartSec=

Налаштовує час очікування на запуск. Якщо фонова служба не сигналізує про завершення запуску протягом налаштованого часу, запуск служби вважатиметься таким, що завершився помилкою, а роботу служби буде знову завершено. Точна дія залежить від параметра TimeoutStartFailureMode=. Приймає безрозмірне значення у секундах або значення проміжку часу, наприклад «5min 20s». Передайте значення «infinity» для вимикання механізму граничного часу очікування. Типове значення DefaultTimeoutStartSec= буде взято з налаштованого у засобі керування, окрім випадку, коли використано Type=oneshot. У випадку використання цього типу час очікування буде типово вимкнено (див. systemd-system.conf(5)).

Якщо служба із типом Type=notify/Type=notify-reload надсилає «EXTEND_TIMEOUT_USEC=...», це може спричинити розширення часу запуску за межі TimeoutStartSec=. Перше отримання цього повідомлення має статися до перевищення TimeoutStartSec=, і щойно час запуску було розширено за межі TimeoutStartSec=, засіб керування службами дозволить продовження запуску служби, якщо служба повторює «EXTEND_TIMEOUT_USEC=...» протягом вказаного інтервалу, аж доки стан запуску служби буде завершено «READY=1». (див. sd_notify(3)).

TimeoutStopSec=

У цього параметра два призначення. По-перше, він налаштовує час очікування для кожної з команд ExecStop=. Якщо під час виконання якоїсь з них буде перевищено час очікування, наступні команди ExecStop= буде пропущено, а роботу служби буде перервано сигналом SIGTERM. Якщо не буде вказано команд ExecStop=, служба отримає сигнал SIGTERM негайно. Цю типову поведінку може бути змінено за допомогою параметра TimeoutStopFailureMode=. По-друге, параметр налаштовує час очікування за самостійне завершення роботи службою. Якщо роботу служби не буде завершено протягом вказаного часу, її буде завершено примусово сигналом SIGKILL (див. KillMode= у systemd.kill(5)). Приймає безрозмірне значення у секундах або значення часового проміжку, наприклад, «5min 20s». Передайте значення «infinity» для вимикання механізму граничного часу очікування. Типове значення DefaultTimeoutStopSec= буде взято з файла налаштування засобу керування служб (див. systemd-system.conf(5)).

Якщо служба із типом Type=notify/Type=notify-reload надсилає «EXTEND_TIMEOUT_USEC=...», це може спричинити розширення часу зупинення за межі TimeoutStopSec=. Перше отримання цього повідомлення має статися до перевищення TimeoutStopSec=, і щойно час зупинення було розширено за межі TimeoutStopSec=, засіб керування службами дозволить продовження зупинення служби, якщо служба повторює «EXTEND_TIMEOUT_USEC=...» протягом вказаного інтервалу, або сама не припинить свою роботу (див. sd_notify(3)).

TimeoutAbortSec=

Цей параметр налаштовує час очікування на завершення служби, коли її виконання було перервано через перевищення часу очікування у засобі нагляду (див. WatchdogSec=). Якщо для служби визначено короткий час TimeoutStopSec=, можна скористатися цим параметром, щоб дати системі більше часу на запис дампу ядра служби. Після завершення часу очікування службу роботу служби буде примусово перервано сигналом SIGKILL (див. KillMode= у systemd.kill(5)). Файл дампу ядра у цьому випадку буде обрізано. Скористайтеся TimeoutAbortSec= для встановлення притомного часу очікування для створення дампів ядра для окремих служб, щоб він був достатньо довгим для запису усіх очікуваних даних, але достатньо коротким для обробки помилки служби протягом короткого проміжку часу.

Приймає безрозмірне значення у секундах або значення проміжку часу, наприклад, «5min 20s». Передайте порожнє значення, щоб пропустити обробку часу очікування на переривання відповідним засобом нагляду і повернутися до TimeoutStopSec=. Передайте значення «infinity» для вимикання механізму граничного часу очікування. Типове значення DefaultTimeoutAbortSec= буде взято з файла налаштування засобу керування служб (див. systemd-system.conf(5)).

Якщо служба із типом Type=notify/Type=notify-reload надсилає SIGABRT самостійно (замість того, щоб покластися на запис дампу ядра програми ядром системи), вона може надіслати «EXTEND_TIMEOUT_USEC=...», щоб продовжити час переривання за межі TimeoutAbortSec=. Перше отримання цього повідомлення має статися до перевищення TimeoutAbortSec=, і щойно час переривання було розширено за межі TimeoutAbortSec=, засіб керування службами дозволить продовження переривання служби, якщо служба повторює «EXTEND_TIMEOUT_USEC=...» протягом вказаного інтервалу, або сама не припинить свою роботу (див. sd_notify(3)).

TimeoutSec=

Скорочення для визначення одразу для TimeoutStartSec= і TimeoutStopSec= вказаного значення.

TimeoutStartFailureMode=, TimeoutStopFailureMode=

Ці параметри налаштовують дію, яку буде виконано у випадку, коли фонова служба не надішле сигналу запуску протягом налаштованого для неї TimeoutStartSec=, і, відповідно, якщо вона не зупинить роботу протягом TimeoutStopSec=. Приймає одне з таких значень: terminate, abort і kill. Типовими значенням для обох параметрів є terminate.

Якщо встановлено значення terminate, службу буде штатно перервано надсиланням сигналу, який вказано за допомогою KillSignal= (типовим сигналом є SIGTERM, див. systemd.kill(5)). Якщо роботу служби не буде перервано, FinalKillSignal= буде надіслано після TimeoutStopSec=. Якщо встановлено значення abort, буде, натомість, надіслано WatchdogSignal=, а TimeoutAbortSec= буде застосовано до надсилання FinalKillSignal=. Цим параметром можна скористатися для аналізу служб, які періодично не вдається запустити або завершити. Якщо використано kill, роботу служби буде негайно перервано надсиланням FinalKillSignal= без будь-якого подальшого часу очікування. Цим параметром можна скористатися для спрощення вимикання служб, роботу яких було завершено помилками.

RuntimeMaxSec=

Налаштовує максимальний час роботи служби. Якщо використано цей параметр, і служба працює довше, ніж вказаний час, її роботу буде перервано і переведено у стан помилки. Зауважте, що цей параметр не впливає на служби Type=oneshot, оскільки їхню роботу буде перервано негайно після завершення активації. Передайте «infinity» (типове значення), щоб усунути обмеження на час роботи.

Якщо служба Type=notify/Type=notify-reload надсилає «EXTEND_TIMEOUT_USEC=...», це може спричинити розширення часу виконання за RuntimeMaxSec=. Перше отримання цього повідомлення має статися до перевищення RuntimeMaxSec=, і щойно час виконання буде розширено за межі RuntimeMaxSec=, засіб керування службами дозволить службі продовжити роботу, якщо служба повторить «EXTEND_TIMEOUT_USEC=...» протягом проміжку часу, який вказано до досягнення завершення роботи служби шляхом «STOPPING=1» (або переривання роботи). (див. sd_notify(3)).

RuntimeRandomizedExtraSec=

Цей параметр вносить зміни до RuntimeMaxSec= збільшенням максимального часу роботи на рівномірно розподілені проміжки від 0 до вказаного значення (у секундах). Якщо не вказано RuntimeMaxSec=, цю можливість буде вимкнено.

WatchdogSec=

Налаштовує час очікування засобу нагляду для служби. Засіб нагляду буде активовано після завершення процедури запуску. Служба має регулярно викликати sd_notify(3) із «WATCHDOG=1» (тобто здійснювати «зондування підтримання зв'язку»). Якщо час між двома такими викликами перевищить налаштований час, службу буде переведено у режим помилки і перервано сигналом SIGABRT (або сигналом, який задано параметром WatchdogSignal=). Якщо для Restart= встановлено значення on-failure, on-watchdog, on-abnormal або always, службу буде автоматично перезапущено. Час, який буде налаштовано тут, буде передано до виконуваного процесу служби у змінній середовища WATCHDOG_USEC=. Це надає змогу фоновим службам автоматично вмикати механізм зондування підтримання зв'язку, якщо для служби увімкнено підтримку засобу нагляду. Якщо використано цей параметр, має бути встановлено NotifyAccess= (див. нижче), щоб відкрити доступ до сокета сповіщення, який надано systemd. Якщо NotifyAccess= не встановлено, його буде неявним чином встановлено у значення main. Типовим значенням є 0, значення, яке вимикає цю можливість. Служба може перевіряти, чи засіб керування службами очікує на сповіщення щодо підтримання зв'язку від засобу нагляду. Див. sd_watchdog_enabled(3), щоб дізнатися більше. Може бути використано sd_event_set_watchdog(3) для вмикання підтримки автоматичного сповіщення від засобу нагляду.

Restart=

Налаштовує, чи має бути перезапущено службу, коли процес служби завершує роботу, його роботу завершують або буде досягнуто перевищення часу очікування. Процес служби може бути основним процесом служби, але він також може бути одним з процесів, який вказано за допомогою ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost= або ExecReload=. Якщо завершення роботи процесу є результатом роботи systemd (наприклад, зупинення або перезапуск служби), службу не буде перезапущено. До часів очікування включають пропущений строк дії «зондування підтримання зв'язку» засобу нагляду і запуску служби, часи очікування перезавантаження і дії із зупинення.

Приймає одне зі значень no, on-success, on-failure, on-abnormal, on-watchdog, on-abort або always. Якщо встановлено значення no (типове значення), службу не буде перезапущено. Якщо встановлено значення on-success, перезапуск буде виконано, лише якщо вихід з процедури служби буде виконано штатно. У цьому контексті штатний вихід означає будь-який з вказаних нижче варіантів:

•код виходу 0;
•для типів, відмінних від Type=oneshot один із сигналів SIGHUP, SIGINT, SIGTERM або SIGPIPE;
•стани виходу та сигнали, які вказано у SuccessExitStatus=.

Якщо встановлено значення on-failure, службу буде перезапущено, коли процес завершує роботу із ненульовим кодом виходу, буде перервано сигналом (включно із дампом ядра, але без згаданих вище чотирьох сигналів),коли буде перевищено час очікування на завершення дії (зокрема перезавантаження служби), і якщо буде активовано налаштований час очікування для засобу нагляду. Якщо встановлено значення on-abnormal, службу буде перезапущено, якщо процес буде перервано сигналом (включно із дампом ядра, але виключно для згаданих вище чотирьох сигналів), коли буде перевищено час очікування на завершення дії або коли буде активовано час очікування для засобу нагляду. Якщо встановлено значення on-abort, службу буде перезапущено, лише якщо процес служи завершить роботу через неперехоплений сигнал, який не вказано як стан штатного завершення роботи. Якщо встановлено значення on-watchdog, службу буде перезапущено, лише якщо буде перевищено час очікування на службу для засобу нагляду. Якщо встановлено значення always, службу буде перезапущено, незалежно від того, чи було її завершено штатно, перервано у нештатному режимі сигналом або завершено унаслідок перевищення часу очікування.

Таблиця 1. Причини виходу та результат дії параметрів Restart=

Параметри перезапуску/Причини виходу no always on-success on-failure on-abnormal on-abort on-watchdog
Безпроблемний код виходу або сигнал   X X        
Проблемний код виходу   X   X      
Проблемний сигнал   X   X X X  
Час очікування   X   X X    
Засіб нагляду   X   X X   X

Як виключення наведеного вище параметра, службу буде перезапущено, якщо код виходу або сигнал буде вказано у RestartPreventExitStatus= (див. нижче) або службу буде зупинено за допомогою systemctl stop або еквівалентної дії. Також служби буде завжди перезапущено, якщо код виходу або сигнал буде вказано у RestartForceExitStatus= (див. нижче).

Зауважте, перезапуск служби підлягатиме обмеженню на частоту запуску модуля, яку налаштовано за допомогою StartLimitIntervalSec= і StartLimitBurst=, див. systemd.unit(5), щоб дізнатися більше.

Встановлення для цього параметра значення on-failure є рекомендованим варіантом для довготривалих служб, призначеним для підвищення надійності роботи шляхом спроб автоматично відновлення після помилок. Для служб, які повинні мати можливість переривати свою роботу самостійно (і уникати негайного перезапуску) альтернативним варіантом є on-abnormal.

RestartMode=

Приймає значення-рядок, яке визначає спосіб перезапуску служби:
•Якщо встановлено значення normal (типове значення), службу перезапускають шляхом переведення її у стан помилки або неактивності.
•Якщо встановлено значення direct, служба переходить до стану активації безпосередньо під час автоматичного перезапуску, пропускаючи стан помилки або неактивності. Буде викликано ExecStopPost=. OnSuccess= і OnFailure= буде пропущено.

Цей параметр корисний у випадках, коли можлива тимчасова непрацездатність залежності, а ми не хочемо, щоб помилки ці тимчасові помилки призводили до помилок у залежних модулях. Якщо для цього параметра встановлено значення direct, залежним модулям не надсилатиметься сповіщення про ці тимчасові помилки.

SuccessExitStatus=

Приймає список визначень станів виходу, які, якщо їх повернуто основним процесом служби, вважатимуться успішним завершенням роботи, окрім звичайних успішних станів виходу 0 і окрім Type=oneshot, сигналів SIGHUP, SIGINT, SIGTERM і SIGPIPE. Визначеннями станів виходу можуть бути числові стани переривання, назви станів переривання або назви сигналів переривання, відокремлені пробілами. Див. розділ «Коди виходу з процесів» («Process Exit Codes») на сторінці підручника systemd.exec(5), щоб ознайомитися зі списком назв станів переривання (для цього параметра знадобиться лише частина без префіксів «EXIT_» або «EX_»). Див. signal(7), щоб ознайомитися зі списком назв сигналів.

Зауважте, що цей параметр не змінює зв'язку між числовими станами виходу та їхніми назвами, тобто, незалежно від того, чи використано цей параметр, 0 все одно буде пов'язано із «SUCCESS» (а отже, типово показано як «0/SUCCESS» у виведенні інструментів) і 1 буде пов'язано із «FAILURE» (а отже, типово показаний як «1/FAILURE») тощо. Параметр керує лише тим, що трапиться у результаті отримання цих станів виходу, і як ці коди буде поширено до стану служби цілком.

Цей параметр можна вказувати декілька разів, у випадку чого список успішних станів виходу буде об'єднано. Якщо для цього параметра буде встановлено значення порожнього рядка, буде відновлено початкове значення списку — усі попередні значення для цього параметра буде відкинуто.

Приклад 1. Служба із параметром SuccessExitStatus=

SuccessExitStatus=TEMPFAIL 250 SIGKILL

Стан виходу 75 (TEMPFAIL), 250 та сигнал переривання SIGKILL вважатимуться штатними перериваннями роботи служби.

Зауваження: для отримання списку станів виходу і трансляції між числовими значеннями стану та назвами можна скористатися systemd-analyze exit-status.

RestartPreventExitStatus=

Приймає список визначень станів виходу, які, якщо їх повернуто основним процесом служби, запобігатимуть автоматичному перезапуску служби, незалежно від параметра перезапуску, налаштованого за допомогою Restart=. Визначення станів виходу може бути числовими кодами виходу або назвами сигналів переривання. Записи слід відокремлювати пробілами. Типовим є порожній список, тому, типово, із налаштованого механізму перезапуску не буде виключено жодного стану виходу. Приклад:
RestartPreventExitStatus=1 6 SIGABRT

призводить до того, що коди виходу 1 і 6 та сигнал переривання SIGABRT не призведуть до автоматичного перезавантаження служби. Цей параметр можна вказувати декілька разів — у цьому випадку списки станів запобігання перезапуску буде об'єднано. Якщо для цього параметра визначено порожній рядок, буде відновлено початкове значення списку, а усі попередні призначення для цього параметра буде відкинуто.

Зауважте, що цей параметр не впливає на процеси, які налаштовано за допомогою ExecStartPre=, ExecStartPost=, ExecStop=, ExecStopPost= або ExecReload=, але лише для основного процесу служби, тобто процесу, який викликано за допомогою ExecStart= або (залежно від Type=, PIDFile=, ...) якимось іншим налаштованим основним процесом.

RestartForceExitStatus=

Приймає список визначень станів виходу, які якщо їх повернуто основних процесом служби, накаже системі автоматично перезапускати службу, незалежно від налаштованого за допомогою Restart= параметра перезапуску. Формат аргументу є подібним до формату RestartPreventExitStatus=.

RootDirectoryStartOnly=

Приймає булевий аргумент. Якщо істина (true), кореневий каталог, як його налаштовано за допомогою параметра RootDirectory= (див. systemd.exec(5), щоб дізнатися більше), буде застосовано лише до процесу, який запущено за допомогою ExecStart=, і не до різноманітних інших команд ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop= і ExecStopPost=. Якщо хибність (false), параметр буде застосовано до усіх налаштованих команд у однаковий спосіб. Типовим є значення false.

NonBlocking=

Встановити прапорець O_NONBLOCK для усіх дескрипторів файлів, які передано за допомогою активації на основі сокетів. Якщо істина (true), усі дескриптори файлів >= 3 (тобто дескриптори, окрім stdin, stdout, stderr), окрім тих, які передано за допомогою механізму сховища дескрипторів (див. FileDescriptorStoreMax=, щоб дізнатися більше), матимуть встановлений прапорець O_NONBLOCK, і отже, перебувають у незаблокованому режимі. Цей параметр буде корисним лише у поєднанні із модулем сокета, як це описано у systemd.socket(5), і не впливає на дескриптори файлів, які, наприклад, було раніше збережено у сховищі дескрипторів файлів. Типовим є значення false.

Note that if the same socket unit is configured to be passed to multiple service units (via the Sockets= setting, see below), and these services have different NonBlocking= configurations, the precise state of O_NONBLOCK depends on the order in which these services are invoked, and will possibly change after service code already took possession of the socket file descriptor, simply because the O_NONBLOCK state of a socket is shared by all file descriptors referencing it. Hence it is essential that all services sharing the same socket use the same NonBlocking= configuration, and do not change the flag in service code either.

NotifyAccess=

Керує доступом до сокета сповіщень стану служби, який доступний через виклик sd_notify(3). Приймає одне з таких значень: none (типовий варіант), main, exec або all. Якщо вказано значення none, від процесів служби не прийматимуться оновлення стану фонових служб, усі повідомлення про оновлення стану буде проігноровано. Якщо вказано значення main, прийматимуться лише оновлення служб від основного процесу служби. Якщо вказано значення exec, буде прийнято лише оновлення служб, які надіслано будь-якими основними або керівними процесами, які походять від однієї з команд Exec*=. Якщо вказано значення all, буде прийнято усі оновлення служб від усіх учасників групи керування служби. Значення цього параметра слід вказувати, щоб зробити відкритим доступ до сокета сповіщень при використанні Type=notify/Type=notify-reload або WatchdogSec= (див. вище). Якщо використано ці параметри, але не налаштовано NotifyAccess=, для цього параметра буде неявним чином встановлено значення main.

Зауважте, що сповіщення sd_notify() може бути належним чином пов'язано із модулями, лише якщо або процес, що їх надіслав, усе ще працює на момент, коли PID 1 обробляє повідомлення, або якщо за процесом, що їх надіслав, явним чином стежить у режимі виконання засіб керування службами. Другий випадок трапляється, якщо засіб керування службами спочатку відгалужує процес, тобто для усіх процесів, які відповідають main або exec. Навпаки, якщо допоміжний процес модуля надсилає повідомлення sd_notify() і негайно завершує роботу, засіб керування службами може не змогти належним чином пов'язати повідомлення із модулем, а отже, проігнорує його, навіть якщо для нього встановлено NotifyAccess=all.

Отже, щоб усунути конкурентність у пошуку модуля клієнта та належної прив'язки сповіщень до модулів, можна скористатися sd_notify_barrier(). Цей виклик працює як точка синхронізації і забезпечує надсилання усіх сповіщень до отримання результатів цього виклику засобом керування службами при успішному поверненні керування. Користуватися sd_notify_barrier() слід для клієнтів, які не викликано засобом керування службами, інакше цей механізм синхронізації стане непотрібним для прив'язування сповіщень до модуля.

Sockets=

Вказує назву модулів сокета цієї служби, від якої буде успадковано дескриптори файлів сокетів при запуску служби. Зазвичай, потреби у використанні цього параметра немає, оскільки усі дескриптори файлів сокетів, чий модуль має таку саму назву, як і служба (за винятком, звичайно ж, іншого суфікса назви модуля), буде передано породженому процесу.

Зауважте, що ті самі дескриптори файлів сокетів може бути передано одночасно декільком процесам. Також зауважте, що для вхідного обміну даними сокетом може бути активовано іншу службу, ніж та, для якої зрештою налаштовано успадкування дескрипторів файлів сокетів. Або, іншими словами, параметр Service= модулів .socket не повинен за значенням збігатися зі зворотним параметром Sockets= файла .service, на який він посилається.

Цей параметр може бути вказано декілька разів — список модулів сокетів буде об'єднано. Зауважте, що можливості очищення списку сокетів після встановлення (наприклад, встановленням для цього параметра порожнього значення) не передбачено.

FileDescriptorStoreMax=

Налаштувати кількість дескрипторів файлів, які може бути збережено у засобі керування службами для служби за допомогою повідомлень «FDSTORE=1» sd_pid_notify_with_fds(3). Корисно для реалізації служб, які можуть перезапускатися після явного запиту або аварії без втрати стану. У цей спосіб може бути збережено будь-які відкриті сокети та інші дескриптори файлів, які не слід закривати під час перезапуску. Стан програми може бути або послідовно переведено до файла у RuntimeDirectory=, або збережено у дескрипторі файла у пам'яті memfd_create(2). Типовою кількістю є 0, тобто у засобі керування службами не можна зберігати дескриптори файлів. Усі дескриптори файлів, які передано до засобу керування службами з певної служби, буде передано назад до основного процесу служби під час наступного перезапуску служби (див. sd_listen_fds(3), щоб дізнатися більше про подробиці використаного протоколу та порядок, у якому передаються дескриптори файлів). Будь-які дескриптори файлів, які передано засобу керування службами, буде автоматично закрито, коли для них стане видимим POLLHUP або POLLERR, або коли роботу служби буде повністю зупинено, і для неї не лишиться завдання у черзі або виконуваного завдання (останнє можна скоригувати за допомогою FileDescriptorStorePreserve=, див. нижче). Якщо використано цей параметр, має бути встановлено NotifyAccess= (див. вище) для відкриття доступу до сокета сповіщень, який надається systemd. Якщо значення NotifyAccess= не встановлено, неявним чином буде використано значення main.

Командою fdstore systemd-analyze(1) можна скористатися для отримання списку поточного вмісту сховища дескрипторів файлів служби.

Зауважте, що засіб керування службами передасть дескриптори файлів, які містяться у сховищі дескрипторів файлів, лише власним процесам служби, ніколи іншим клієнтам за IPC або подібним протоколом. Втім, він дозволяє непривілейованим клієнтам надсилати запит щодо списку поточних відкрити дескрипторів файлів служби. Тому до таких файлів можна безпечно записувати конфіденційні дані, але не слід долучати їх до метаданих (наприклад, включених до назв файлів) збережених дескрипторів файлів.

Якщо для цього параметра встановлено ненульове значення, для процесів, викликаних для цієї служби, буде встановлено змінну середовища $FDSTORE. Див. systemd.exec(5), щоб дізнатися більше.

Щоб дізнатися більше про сховище файлових дескрипторів, ознайомтеся із оглядом щодо сховища файлових дескрипторів[1].

FileDescriptorStorePreserve=

Приймає одне зі значень no, yes, restart і керує тим, коли слід очищувати сховище дескрипторів файлів служби (тобто тим, коли закривати дескриптори файлів, що у ньому містяться, якщо такі є). Якщо встановити значення no, сховище файлових дескрипторів буде автоматично очищено, щойно роботу служби буде зупинено; якщо значення restart (типове), вміст сховища зберігатиметься, доки модуль не перейде у стан неактивності або помилки, або до черги буде додано завдання для служби, або система очікуватиме на перезапуск служби. Якщо встановити значення yes, вміст сховища зберігатиметься, доки модуль не буде вилучено з пам'яті (тобто не буде більше посилань на модуль і модуль стане неактивним). Останній варіант корисний для збереження у сховищі дескрипторів файлів записів до завершення роботи засобу керування службами.

Скористайтеся systemctl clean --what=fdstore ..., щоб очистити сховище дескрипторів файлів явним чином.

USBFunctionDescriptors=

Налаштувати місце для файл, який містить дескриптори USB FunctionFS[2] для реалізації функціональних можливостей гаджетів USB. Використовують у поєднанні із модулем сокетів із налаштованим ListenUSBFunction=. Вміст цього файла буде записано до файла ep0 після того, як його буде відкрито.

USBFunctionStrings=

Налаштувати розташування файла, який містить рядки FunctionFS USB. Поведінка подібна до USBFunctionDescriptors=, описаного вище.

OOMPolicy=

Налаштувати правила завершення роботи через перевищення обсягу пам'яті (OOM) для ядра та засіб завершення роботи для OOM у просторі користувача systemd-oomd.service(8). У Linux, коли не вистачає пам'яті, аж до стану, коли у ядра виникають проблеми із отриманням пам'яті під свої власні завдання, воно може вирішити завершити запущений процес для вивільнення пам'яті і зменшення напруженості щодо пам'яті. Зауважте, що systemd-oomd.service є гнучкішим рішенням, метою якого є запобігти ситуаціям із вичерпанням пам'яті і у просторі користувача, не лише у ядрі, шляхом спроби переривання служб на ранньому етапі, до того, як до справи береться ядро.

Цей параметр приймає одне з таких значень: continue, stop або kill. Якщо встановлено значення continue, і процес модуля буде завершено засобом запобігання OOM, дані про завершення роботи буде записано до журналу, але модуль продовжить роботу. Якщо встановлено значення stop, запис події буде додано до журналу, а роботу модуля буде штатно перервано засобом керування службами. Якщо встановлено значення kill, і один із процесів модуля буде завершено засобом припинення роботи OOM, ядру буде наказано припинити роботу решти процесів модуля встановленням атрибуту memory.oom.group у значення 1; див. також документацію до ядра системи[3].

Типовим для параметра є значення DefaultOOMPolicy= у systemd-system.conf(5), окрім модулів, для яких увімкнено Delegate=, де типовим значенням є continue.

Скористайтеся параметром OOMScoreAdjust= для налаштовування того, чи будуть процеси модуля пріоритетними кандидатами на переривання роботи механізмами завершення роботи у результаті OOM Linux. Див. systemd.exec(5), щоб дізнатися більше.

Цей параметр також стосується systemd-oomd.service(8); подібно до OOM-завершень, що виконується ядром, цей параметр визначає стан модуля після того, як systemd-oomd знищить cgroup, яку пов'язано із модулем.

OpenFile=

Приймає аргумент у формі «шлях[:назва-дескриптора-файла:параметри]», де
•«шлях» є шляхом до файла або сокета AF_UNIX у файловій системі;
•«назва-дескриптора-файла» є назвою, яку буде пов'язано із дескриптором файла; назва може містити будь-які символи ASCII, але у ній не повинно бути керівних символів та «:»; крім того, її довжина не повинна перевищувати 255 символів; вона є необов'язковою і, якщо її не вказано, типово є назвою файла;
•«параметри» є списком відокремлених комами параметрів доступу; можливими значеннями є «read-only», «append», «truncate», «graceful»; якщо не вказано, файли буде відкрито у режимі rw; якщо вказано «graceful», помилки під час спроби відкрити файл або сокет буде проігноровано. Визначення того самого параметра декілька разів вважатиметься помилкою.

Файл або сокет буде відкрито засобом керування службами, а дескриптор файла буде передано службі. Якщо шлях є сокетом, для нього буде викликано connect(). Див. sd_listen_fds(3), щоб дізнатися більше про те, як отримати ці дескриптори файлів.

Цей параметр корисний для уможливлення для служб доступу до файлів або сокетів, доступ до яких вони не можуть отримати самі (через запуск у окремому просторі назв монтування, недостатні привілеї тощо).

Можна вказати декілька таких параметрів одночасно; у такому випадку буде відкрито усі вказані шляхи, а дескриптори файлів передано службі. Якщо буде призначено порожній рядок, буде скинуто увесь список відкритих файлів, які було визначено до цього призначення.

ReloadSignal=

Налаштовує сигнал процесу UNIX, який буде надіслано до основного процесу служби при запиті щодо перезавантаження налаштувань служби. Типовим сигналом є SIGHUP. Цей параметр ні на що не впливає, якщо не використано Type=notify-reload, див. вище.

Ознайомтеся зі сторінками підручника щодо systemd.unit(5), systemd.exec(5) і systemd.kill(5), щоб дізнатися більше про інші параметри.

РЯДКИ КОМАНД

У цьому розділі описано обробку рядка команди і підставляння змінних і специфікаторів для параметрів ExecStart=, ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop= і ExecStopPost=.

Декілька рядків команд може бути об'єднано у одну інструкцію, розділивши їх крапкою з комою (ці крапки з комами має бути передано як окремі слова). Окремі крапки з комами можна екранувати: «\;».

Екранування у кожному з рядків команд буде вилучено з використанням правил, які описано у розділі «Нейтралізація» («Quoting») на сторінці підручника systemd.syntax(7). Перший запис стане командою, яку слід виконати, а наступні записи є аргументами команди.

Цей синтаксис є похідним від синтаксису командної оболонки, але буде розпізнано лише метасимволи і розгортання з наступних абзаців, а розгортання змінних є іншим. Зокрема, не передбачено підтримки елементів синтаксису командної оболонки, зокрема переспрямування за допомогою «<», «<<», «>» і «>>», каналів переспрямовування за допомогою «|», запуску програм у фоновому режимі за допомогою «&».

Запис команди для виконання може містити пробіли, але не можна використовувати керівні символи.

До кожної з команд можна дописати префікс із декількома спеціальними символами:

Таблиця 2. Особливі префікси виконуваних файлів

Префікс Результат
"@" Якщо шлях до виконуваного файла має префікс «@», другий вказаний елемент буде передано як argv[0] до виконуваного процесу (замість справжньої назви файла), а потім подальші вказані аргументи.
"-" Якщо шлях до виконуваного файла має префікс «-», код виходу з команди, який за звичайних умов вважається критичною помилкою (тобто ненульовий стан виходу або ненормальний вихід через надсилання сигналу), буде записано, але не матиме подальшого впливу на роботу і вважатиметься еквівалентом успіху.
":" Якщо шлях до виконуваного файла має префікс «:», не буде застосовано заміну змінних середовища (як це описано у розділі «РЯДКИ КОМАНД» нижче).
"+" Якщо шлях до виконуваного файла має префікс «+», процес буде виконано із усіма привілеями. У цьому режимі обмеження привілеїв, яке налаштовано за допомогою User=, Group=, CapabilityBoundingSet= або різноманітних параметрів простору назв файлової системи (зокрема PrivateDevices=, PrivateTmp=), не буде застосовано до викликаного рядка команди (але вони усе ще впливатимуть на будь-які інші рядки ExecStart=, ExecStop=, ...). Втім, зауважте, що це не призведе до ігнорування параметрів, які застосовуються до усієї групи керування, зокрема DevicePolicy=; див. systemd.resource-control(5), щоб ознайомитися із повним списком.
"!" Подібно до символу «+», обговорення якого наведено вище, цей символ надає змогу викликати рядки команд із розширеними привілеями. Втім, на відміну від «+», символ «!» виключно змінює наслідки застосування User=, Group= і SupplementaryGroups=, тобто лише фрагменти, які стосуються реєстраційних даних користувача і групи. Зауважте, що цей параметр можна поєднувати із DynamicUser=, у випадку чого динамічну пару користувач/група буде створено перед викликом команди, але зміна реєстраційних даних буде покладено на сам виконуваний процес.
"!!" Цей префікс є дуже подібним до «!», втім, він працює лише у системах, де немає підтримки можливості зовнішніх процесів, тобто без підтримки AmbientCapabilities=. Його призначено для використання для файлів модулів, у яких використано зовнішні можливості для запуску, де це можливо, процесів з мінімальними привілеями, не порушуючи сумісності з системами, у яких не передбачено підтримки зовнішніх можливостей. Зауважте, що якщо використано «!!» і буде виявлено, що у системі немає підтримки зовнішніх можливостей, усі налаштовані команди SystemCallFilter= і CapabilityBoundingSet= буде неявним чином змінено, щоб надати змогу породженим процесам скидати реєстрацію та можливості самостійно, навіть якщо налаштуваннями це заборонено. Більше того, якщо буде використано цей префікс, і буде виявлено нестачу підтримки зовнішніх можливостей, AmbientCapabilities= буде пропущено і не буде застосовано. У системах з підтримкою зовнішніх можливостей, «!!» ні на що не впливає і є зайвим.

«@», «-», «:» і один із префіксів «+»/«!»/«!!» можна поєднати у будь-якому порядку. Втім, одночасно можна використовувати лише один з префіксів «+», «!», «!!».

Для усіх команд першим аргументом має бути або абсолютний шлях до виконуваного файла або проста назва файла без символів похилих рисок. Якщо команда не є повним (абсолютним) шляхом, її буде оброблено як повний шлях з використанням фіксованого шляху пошуку, який визначено під час компіляції. Серед каталогів для пошуку /usr/local/bin/, /usr/bin/, /bin/ у системах, у яких використано окремі каталоги /usr/bin/ і /bin/, та їхні відповідники з sbin/ у системах, де використано окремі каталоги bin/ і sbin/. Таким чином, можна безпечно скористатися простою назвою виконуваного файла, якщо виконувані файли зберігаються у будь-якому із «стандартних» каталогів. У інших випадках слід користуватися абсолютним шляхом. Рекомендовано для уникнення неоднозначності користуватися абсолютними шляхами. Підказка: список шляхів для пошуку можна отримати за допомогою команди systemd-path search-binaries-default.

У рядку команди можна використовувати специфікатори «%», як їх описано на сторінці підручника щодо systemd.unit(5).

Передбачено підтримку заміни базових змінних середовища. Скористайтеся «${ЩОСЬ}», як частиною слова, або окремим словом у рядку команди; цей рядок буде замінено точним значенням змінної середовища (якщо таке визначено) разом із усіма пробілами, які у ньому містяться, так, щоб результатом був завжди один аргумент. Скористайтеся «$FOO», як окремим словом, у рядку команди; цей рядок буде замінено на значення змінної середовища, поділену на пробілах — результатом буде нуль або більше аргументів. Для цього типу розгортання лапки буде враховано при поділі на слова, а після цього буде вилучено.

Приклад:

Environment="ONE=one" 'TWO=two two'
ExecStart=echo $ONE $TWO ${TWO}

Буде виконано /bin/echo із чотирма аргументами: «one», «two», «two» і «two two».

Приклад:

Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
ExecStart=/bin/echo $ONE $TWO $THREE

Результатом буде виклик /bin/echo двічі, перший раз із аргументами "'one'", "'two two' too", "", а другий раз із аргументами "one", "two two", "too".

Щоб передати сам символ долара, скористайтеся "$$". Змінні, чиї значення є невідомими, під час розгортання буде оброблено як порожні рядки. Зауважте, що перший аргумент (тобто програма, яку слід виконати) не може бути змінною.

Змінні, які буде використано у цей спосіб, можна визначити за допомогою Environment= і EnvironmentFile=. Крім того, може бути використано змінні зі списку «Змінні середовища у породжених процесах» («Environment variables in spawned processes») сторінки підручника щодо systemd.exec(5), які вважають «статичними налаштуваннями» (це стосується, зокрема, $USER, але не $TERM).

Зауважте, безпосередньої підтримки рядків команд оболонки не передбачено. Якщо має бути використано рядки команд оболонки, їх слід передати явним чином до реалізації командної оболонки якогось типу. Приклад:

ExecStart=sh -c 'dmesg | tac'

Приклад:

ExecStart=echo one ; echo "two two"

Буде виконано echo двічі, кожного разу із одним аргументом: "one" і "two two", відповідно. Оскільки задано дві команди, слід використовувати Type=oneshot.

Приклад:

Type=oneshot
ExecStart=:echo $USER ; -false ; +:@true $TEST

Буде виконано /usr/bin/echo із буквальним аргументом «$USER» («:» придушує розгортання змінних), а потім /usr/bin/false (повернуте значення буде проігноровано, оскільки «-» придушує перевірку повернутого значення) і /usr/bin/true (із підвищеними привілеями з «$TEST» як argv[0]).

Приклад:

ExecStart=echo / >/dev/null & \; \
ls

Буде виконано echo із п'ятьма аргументами: "/", ">/dev/null", "&", ";" і "ls".

ПРИКЛАДИ

Приклад 2. Проста служба

Вказаний нижче файл модуля створює службу, яка виконає фонову службу /usr/sbin/foo-daemon. Оскільки Type= не вказано, буде неявним чином використано Type=simple. systemd припускатиме, що модуль буде запущено негайно після того, як почнеться виконання програми.

[Unit]
Description=Foo
[Service]
ExecStart=/usr/sbin/foo-daemon
[Install]
WantedBy=multi-user.target

Зауважте, що systemd тут припускає, що виконання процесу, запущеного за допомогою systemd, продовжуватиметься, аж доки роботу служби не буде припинено. Якщо програма сама себе переводить у режим фонової служби (тобто виконує відгалуження), будь ласка, скористайтеся Type=forking.

Оскільки не вказано ExecStop=, systemd надішле SIGTERM усім процесам, які запущено з цієї служби, і після завершення часу очікування, також SIGKILL. Цю поведінку можна змінити, див. systemd.kill(5), щоб дізнатися більше.

Зауважте, що до цього типу модулів не включено жодного типу сповіщень щодо завершення службою ініціалізації. Для цього вам слід користуватися іншими типами модулів, зокрема Type=notify/notify-reload, якщо служба розуміє протокол сповіщень systemd, Type=forking, якщо служба може перевести себе у фоновий режим, або Type=dbus, якщо модуль отримує назву DBus, щойно ініціалізацію буде завершено. Див. нижче.

Приклад 3. Служба oneshot

Іноді, модулі мають просто виконати дію без підтримання процесів активними, зокрема виконати перевірку файлової системи або дію з чищення при завантаженні системи. Для цього існує Type=oneshot. Модулі цього типу чекатимуть на завершення вказаного процесу, а потім повертатимуться до неактивного стану. Дію з чищення буде виконано таким модулем:

[Unit]
Description=Чищення якихось застарілих даних
[Service]
Type=oneshot
ExecStart=/usr/sbin/foo-cleanup
[Install]
WantedBy=multi-user.target

Зауважте, що systemd вважатиме модуль таким, що перебуває у стані «запуск», аж доки роботу програми не буде перервано, отже, упорядковані залежності чекатимуть на завершення роботи програми до свого запуску. Модуль повернеться до стану «неактивний» після завершення виконання — він ніколи не досягне стану «активний». Це означає, що ще один запит щодо запуску модуля, призведе до повторного виконання дії.

Type=oneshot є єдиними модулями служб, для яких можна вказувати декілька ExecStart=. Для модулів із декількома командами (Type=oneshot), буде знову запущено усі команди.

Для Type=oneshot not можна використовувати Restart=always і Restart=on-success.

Приклад 4. Придатна до зупинки одноразова служба

Подібно до одноразових служб, іноді існують модулі, які мають виконати програму для налаштовування чогось, а потім виконати іншу програму для завершення цієї програми, але не буде активного процесу, доки ці програми вважатимуться «запущеними». Налаштування мережі можуть іноді потрапляти до цієї категорії. Іншим випадком може бути одноразова служба, яку не буде виконано кожного разу, а лише першого разу, коли її викликатимуть як залежність.

Для цього systemd отримує параметр RemainAfterExit=yes, який спричиняє те, що systemd вважатиме модуль активним, якщо дію із запуску буде успішно завершено. Цю директиву може бути використано із усіма типами, але найкорисніша вона з Type=oneshot і Type=simple. З Type=oneshot systemd очікує, доки буде завершено дію із запуску, перш ніж почне вважати, що модуль є активним, тому запуск залежностей розпочнеться після успішного завершення дії із запуску. З Type=simple залежності буде запущено негайно після розміщення у розкладі дії із запуску. Наведений нижче модуль є прикладом для простого статичного брандмауера.

[Unit]
Description=Simple firewall
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/simple-firewall-start
ExecStop=/usr/local/sbin/simple-firewall-stop
[Install]
WantedBy=multi-user.target

Оскільки модуль вважається таким, що працює, після завершення дії зі запуску, повторний виклик systemctl start для цього модуля не призведе до виконання жодних дій.

Приклад 5. Традиційні служби із відгалуженням

Багато традиційних фонових та звичайних служб під час запуску переводять себе у фоновий режим (тобто виконують відгалуження, переведення у режим демона). Встановіть Type=forking у файлі модуля служби для підтримки цього режиму роботи. systemd вважатиме службу такою, що перебуває у процесі ініціалізації, доки початкова програма продовжуватиме роботу. Щойно роботу програми буде успішно завершено, і лишиться принаймні один процес (і RemainAfterExit=no), служба вважатиметься запущеною.

Часто традиційна фонова служба складається з одного процесу. Тому, якщо після завершення початкового процесу лишається лише один процес, systemd вважатиме цей процес основним процесом служби. У цьому випадку змінна $MAINPID буде доступною у ExecReload=, ExecStop= тощо.

Якщо лишиться більше одного процесу, systemd не зможе визначити основний процес, тому не вважатиме, що такий процес існує. У такому випадку $MAINPID матиме порожнє значення. Втім, якщо процес вирішить записати традиційний PID, systemd зможе прочитати основний PID з нього. Будь ласка, встановіть PIDFile= відповідним чином. Зауважте, що фонова служба має записати цей файл до завершення ініціалізації. Якщо цього не буде зроблено, systemd може спробувати прочитати файл, перш ніж він почне існувати.

У наведеному нижче прикладі показано просту фонову службу, яка відгалужує і просто запускає один процес у фоновому режимі:

[Unit]
Description=Якась проста фонова служба
[Service]
Type=forking
ExecStart=/usr/sbin/my-simple-daemon -d
[Install]
WantedBy=multi-user.target

Будь ласка, ознайомтеся зі сторінкою підручника щодо systemd.kill(5), щоб дізнатися більше про те, як вплинути на спосіб, у який systemd перериває роботу служби.

Приклад 6. Служби DBus

Для служб, яка надсилає запит щодо назви на системному каналі DBus, скористайтеся Type=dbus і встановіть BusName= відповідним чином. Служба не повинна виконувати відгалуження (переходити у фоновий режим). systemd вважатиме службу ініціалізованою, щойно буде отримано назву на системному каналі. У наведеному нижче прикладі показано типову службу DBus:

[Unit]
Description=Проста служба DBus
[Service]
Type=dbus
BusName=org.example.simple-dbus-service
ExecStart=/usr/sbin/simple-dbus-service
[Install]
WantedBy=multi-user.target

Для служб bus-activatable не включайте розділ [Install] у файлі служби systemd, а скористайтеся параметром SystemdService= у відповідному файлі служби DBus. Приклад (/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):

[D-BUS Service]
Name=org.example.simple-dbus-service
Exec=/usr/sbin/simple-dbus-service
User=root
SystemdService=simple-dbus-service.service

Будь ласка, ознайомтеся зі сторінкою підручника щодо systemd.kill(5), щоб дізнатися більше про те, як вплинути на спосіб, у який systemd перериває роботу служби.

Приклад 7. Служби, які сповіщають systemd про свою ініціалізацію

Служби Type=simple дуже просто писати, але у них є великий недолік — для таких служб systemd не зможе визначити, коли завершено ініціалізацію служби. Через це, у systemd передбачено підтримку простого протоколу сповіщення, за допомогою якого фонові служби можуть повідомляти systemd про завершення ініціалізації. Для того, щоб ним скористатися, використайте Type=notify або Type=notify-reload. Типовий файл служби для такої фонової служби має виглядати ось так:

[Unit]
Description=Проста служба сповіщення
[Service]
Type=notify
ExecStart=/usr/sbin/simple-notifying-service
[Install]
WantedBy=multi-user.target

Зауважте, що у фоновій службі має бути передбачено підтримку протоколу сповіщень systemd, інакше systemd вважатиме, що службу ще не запущено і завершить її роботу, щойно завершиться відлік часу очікування. Приклад того, як оновлювати фонові служби для забезпечення прозорої підтримки цього протоколу, наведено у підручнику з sd_notify(3). systemd вважатиму модуль таким, що перебуває у стані «запуск», доки не буде отримано сповіщення про готовність.

Будь ласка, ознайомтеся зі сторінкою підручника щодо systemd.kill(5), щоб дізнатися більше про те, як вплинути на спосіб, у який systemd перериває роботу служби.

ДИВ. ТАКОЖ

systemd(1), systemctl(1), systemd-system.conf(5), systemd.unit(5), systemd.exec(5), systemd.resource-control(5), systemd.kill(5), systemd.directives(7), systemd-run(1)

ПРИМІТКИ

1.
Сховище дескрипторів файлів
2.
USB FunctionFS
3.
документація до ядра

ПЕРЕКЛАД

Український переклад цієї сторінки посібника виконано Yuri Chornoivan <yurchor@ukr.net>

Цей переклад є безкоштовною документацією; будь ласка, ознайомтеся з умовами GNU General Public License Version 3. НЕ НАДАЄТЬСЯ ЖОДНИХ ГАРАНТІЙ.

Якщо ви знайшли помилки у перекладі цієї сторінки підручника, будь ласка, надішліть електронний лист до списку листування перекладачів: trans-uk@lists.fedoraproject.org.

systemd 254