Назад | Перейти на главную страницу

systemd unit останавливается, когда требуемый модуль останавливается, но затем не запускается снова, когда запускается требуемый модуль

У меня есть подразделение, которое я просто позвоню eth-service это требует другого подразделения, которое я позвоню eth-server. В модульном файле eth-service у меня есть

Requires=eth-server.service
After=eth-server.service

Теперь, когда я бегу systemctl stop eth-server, затем eth-service останавливается, как и должно. Однако позже, когда я бегу systemctl start eth-server, К сожалению eth-service остается неактивным, поэтому мне нужно не забыть перезапустить его.

Я пытаюсь сделать настройку моего файла модуля максимально защищенной от идиотов (особенно против меня самого) - можно ли настроить мои файлы модуля так, чтобы при запуске сервера служба тоже делала это? Если бы я положил в свой eth-server файл модуля:

Requires=eth-service.service
Before=eth-service.service

так что они взаимно требуют друг друга, что вызовет запуск службы, когда это делает сервер, но это также означает, что когда я запускаю systemctl stop eth-service затем eth-server тоже останавливается, так как теперь требуется услуга, что нежелательно.

Позвольте мне посмотреть, понял ли я сценарий использования:

  1. Запуск eth-service должен начать оба eth-server и eth-service.
  2. Запуск eth-server должен начать оба eth-server и eth-service.
  3. Остановка eth-server должен остановить оба eth-server и eth-service.
  4. Остановка eth-service должен ТОЛЬКО остановиться eth-service и уходи eth-server Бег.

Вы можете добиться этого, добавив WantedBy=eth-server.service в раздел [Установить] eth-service.service файл или Wants=eth-service.service в раздел [Unit] eth-server.service.

Согласно документация systemd Wants это более слабая версия Requires, и кажется, что если Wanted блок остановлен, запрошенный блок не затронут. Но в этой настройке может быть нежелательный побочный эффект, когда eth-server начнется независимо от того, если eth-service не запускается или нет.

Примеры файлов юнитов

Следующие образцы файлов модулей можно сохранить в домашнем каталоге (~/.config/systemd/user) и используется с systemctl --user параметр.

Сервисы, описываемые этими юнит-файлами, ничего не делают, но RemainAfterExit=yes заставляет systemd предполагать, что служба все еще работает, даже если /bin/true команда не остается после выполнения.

etc-service.service

[Unit]
Description=eth Service
Requires=eth-server.service

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes

[Install]
WantedBy=eth-server.service

eth-server.service

[Unit]
Description=eth Server

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes

Включите eth-service.service модуль с systemctl --user enable eth-service.service.

Ниже приведены результаты тестов с запуском / остановкой служб:

Начальное состояние

$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

$> systemctl --user status eth-server
● eth-server.service - eth Server
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
  Active: inactive (dead)

Система возвращается в исходное состояние перед выполнением команд в следующих двух разделах.

systemctl --user start eth-service.service

Обе server и service запущены (игнорируйте exited строки: и сервер, и служба являются выполнением / bin / true, который завершается после завершения, но файлы модулей записываются так, что systemd будет думать, что службы работают, пока они не будут остановлены)

$> systemctl --user start eth-service.service 
$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 28s ago
  Process: 1578 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1578 (code=exited, status=0/SUCCESS)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
  Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 2min 59s ago
 Process: 1579 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1579 (code=exited, status=0/SUCCESS)

systemctl --user start eth-server.service

Обе службы запущены:

$> systemctl --user start eth-server.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
  Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 7s ago
 Process: 1681 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1681 (code=exited, status=0/SUCCESS)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 12s ago
  Process: 1680 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1680 (code=exited, status=0/SUCCESS)

Команды в следующих двух разделах выполняются там, где запущены обе службы:

systemctl --user stop eth-server.service

$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: inactive (dead)

Вы можете видеть, что обе службы были остановлены

systemctl --user stop eth-service

$> systemctl --user stop eth-service
$> systemctl --user status eth-service
● eth-service.service - eth Service
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
  Active: inactive (dead) since Tue 2018-05-29 21:05:25 IST; 34s ago
 Process: 1800 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1800 (code=exited, status=0/SUCCESS)

May 29 21:04:23 ektich systemd[479]: Starting eth Service...
May 29 21:04:23 ektich systemd[479]: Started eth Service.
May 29 21:05:25 ektich systemd[479]: Stopped eth Service.

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 21:04:23 IST; 2min 58s ago
  Process: 1799 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1799 (code=exited, status=0/SUCCESS)

May 29 21:04:23 ektich systemd[479]: Starting eth Server...
May 29 21:04:23 ektich systemd[479]: Started eth Server.

Ты это видишь eth-service был остановлен (Active: inactive (dead)) но eth-server все еще "работает" (Active: active)

Команда статуса для etc-service произвел больше результатов по сравнению с другими случаями, я предполагаю, потому что «транзакция» еще не завершена (etc-server все еще работает). Дополнительные строки из journalctl показать, что что касается systemd, одна из служб была остановлена, а другая все еще работает.

PS согласно домашняя страница systemd это пишется systemdне SystemD (просто педантично)

В systemctl start xxx в общем-то не возвращается последствия предыдущего systemctl stop xxx.

Админы должны понимать это в ходе своей карьеры, так или иначе. Хорошая новость в том, что этому действительно легко научиться, потому что обратная связь сразу же.

Один из способов отменить ручные остановки и ручные запуски:

systemctl default 

Но этот способ вряд ли является надежным, так как он останавливает службы, которые не включен, например, службы, работающие в различных кластерах (в частности, кардиостимулятор даже не видит в этом проблему / сбой и не реагирует на нее - он рассматривает это как запланированное действие администратора).

А также есть systemctl snapshot но это еще более сложно и, следовательно, менее надежно.

Что вы можете сделать в рамках своих услуг (чтобы стать более защищенным от дурака)? Обратите внимание, как с этим справились другие программисты. Они избегают зависимостей и предпочитают упаковывать несколько процессов в одну зонтичную службу. В стандартной установке RHEL7 нет никаких зависимостей служб. Например постфикс:

$ systemctl status postfix
[...] Tasks: 3
   CGroup: /system.slice/postfix.service
           ├─1288 /usr/libexec/postfix/master -w
           ├─1290 qmgr -l -t unix -u
           └─7340 pickup -l -t unix -u

$ cat /usr/lib/systemd/system/postfix.service
[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service

[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop

[Install]
WantedBy=multi-user.target