Як налаштувати systemd, щоб вбити та перезапустити демон при перезавантаженні?


12

У мене є старий шкільний демон, який я хочу контролювати за допомогою systemd. Коли файл конфігурації змінюється, його потрібно вбити та перезапустити. Іншими словами, після редагування конфігураційного файлу systemctl reload MYSERVICEслід вбити процес і перезапустити його.

Спроба 1: Спробуйте налаштування за замовчуванням. Це розповідає systemd, як запустити демон, але не як його перезавантажити.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Як результат, startі restartробота, але reloadдає цю помилку:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Спроба 2: Розкажіть, як вбити процес. Це вбиває процес, але systemd не перезапускає його для мене.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

... далі ...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... вбиває процес, але він не запускається автоматично.

Спроба 3: Використовуйте ExecReload і для перезапуску процесу. Це не вдається з кількох причин:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... повідомлення про помилку, яке я отримую ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Я б очікував, що буде ReloadType = kill_and_restart або щось подібне, але такої удачі немає.

Як сказати systemd вбити та перезапустити демон при перезавантаженні?


Це дійсно потрібно підключити до перезавантаження , де воно не зовсім точно підходить? Ви не можете змусити демона вести себе розважливо?
Майкл Хемптон

Дякую @MichaelHampton, але це не така ситуація, коли я можу переписати програму. Я вдячний за вашу корисну пропозицію. Однак я впевнений, що це звичайний системний випадок використання, і канонічна відповідь може допомогти багатьом людям.
TomOnTime

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

Відповіді:


16

Відповідь - "ти цього не робиш"! Але у нас є хороші новини.

Філософія systemd полягає в тому, що перезавантаження не є обов'язковим і його слід залишати невизначеним, якщо немає справжньої функції перезавантаження. Я б визначив "справжню функцію перезавантаження" як перезавантаження, яка не вбиває і не перезапустить службу, або змусить службу змінити PID. Іншими словами, systemd хоче лише відобразити, які функції існують.

Натомість слід скористатись функцією, systemctl reload-or-restartяка виконає перезавантаження, якщо вона існує, і перезапуск, якщо вона не відбудеться.

Зі сторінки чоловіка ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Отже: (1) залиште ExecReload порожнім, (2) використовуйте systemctl reload-or-restart MYSERVICEта (3) у вас все буде налаштовано.

Якщо ви спробуєте використовувати ExecReload для визначення способу вбивства та перезапуску служби, у неї з’явиться новий PID, і systemd буде заплутаний.


3

Філософія systemd полягає в тому, що reloadце необов'язково, і користувач systemd повинен знати для кожної послуги, чи повинен він телефонувати reloadабо підробляти її за допомогою дзвінка restart.

Тому відповідь на ваше запитання: "Це не працює, і не повинно. Будь ласка, вирішіть це на наступному більш високому шарі".

Іншими словами, systemd хоче, щоб ви реалізували " перезавантажувати " лише тоді, коли базовий сервіс підтримує справжню функцію перезавантаження ... тобто перезавантаження, яке не вбиває і не запускає службу, або змушує службу змінити свій PID. Іншими словами, systemd хоче лише відобразити, які функції існують.

Ви можете запитати себе: але чи не було б легше, якби я міг здійснити "підроблене" перезавантаження, дозволяючи ExecReloadвбивати та перезапускати службу? Тоді я міг би користуватися systemctl reload FOOвсіма своїми послугами, і мені не потрібно було б пам’ятати, які з них підтримують, а які ні?

Так, це було б простіше, але це не було б системним шляхом. Systemd хоче, щоб абонент був тим, що знає, чи reloadіснує для послуги. Systemd хоче бути загальним інтерфейсом до існуючих функцій, він не хоче відповідати за заповнення прогалин.

Наприклад, маріонетка передбачає, що система, керована системою, не має reloadі за замовчуванням вбиває і перезапускає процес . Якщо тип Service [] додав спосіб вказати, що перезавантаження існує, і що його слід використовувати при сповіщенні, йому потрібно буде дізнатися, які служби мають або не мають власного перезавантаження. Шеф-кухар та всі інші системи також повинні були б навчитися тому ж, оскільки systemd хоче, щоб це було вирішено на цьому шарі. (MiniRant: для запуску процесу systemd здається всезнаючою, всемонтажною, простою іменами, що налаштовує систему i-do-everything-at-my-layer. Тому я не можу сказати, чому це не так розширити цю філософію на перезавантаження. Можливо, хтось із авторів тут може зазивати.)


1
Є systemctl reload-or-restart, яка перезавантажить службу, якщо вона її підтримує, і перезапустить її, якщо вона не працює. Не маю уявлення, чому Лялька робить таке припущення.
Майкл Хемптон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.