Вопрос или проблема
Всякий раз, когда я включаю определенную экземплярную службу systemd, я хочу, чтобы также были включены два таймера с тем же указателем экземпляра. Вот как выглядит мой файл юнита [email protected]:
[Unit] Description=Does something cool Documentation=man:foo(1)
[Service] Type=forking ExecStart=/usr/bin/foo %i PIDFile=%t/foo/foo.pid StandardOutput=journal
[Install] WantedBy=network-online.target Also=bar1@%i.timer Also=bar2@%i.timer
Запуск systemctl enable [email protected]
возвращает:
Failed to enable unit: Invalid argument
Если я удалю указатели экземпляров из раздела [Install] и заменю их конкретными именами экземпляров (чтобы это выглядело следующим образом), то все работает нормально.
... [email protected] [email protected]
Справочное руководство systemd.unit(5) говорит, что указатель %i интерпретируется в установочном разделе, так что происходит?
The following specifiers are interpreted in the Install section: %n, %N, %p, %i, %U, %u, %m, %H, %b, %v.
Кажется, это ошибка в systemd, которая воспроизводится для директивы Also
в разделе [Install]
.
Однако есть обходной путь, который дает такую же функциональность.
Предположим, у вас есть файл [email protected]
, и вы хотите соответствующий файл юнита. Добавьте условие в директиву WantedBy
. Включите юниты .timer
сначала с помощью systemctl enable [email protected]
и т. д.
[Install] WantedBy=network-online.target bar1@%i.timer bar2@%i.timer
Указанное выше хорошо работает для запуска нескольких mpd служб через активацию сокета с использованием шаблона службы и нескольких файлов сокетов.
Ответ или решение
Для решения этой проблемы с systemd, когда вы хотите связать несколько таймеров с одной и той же спецификатором экземпляра, можно воспользоваться альтернативным подходом, который описан в вашей задаче. Основная проблема заключается в том, что использование конструкции Also=bar1@%i.timer bar2@%i.timer
в секции [Install]
вызывает ошибку, хотя в документации указывается, что спецификатор %i
можно использовать в этой секции.
Теория
На данном этапе проблема возникает из-за того, что systemd в данном случае некорректно обрабатывает спецификатор %i
для директивы Also
. Это мешает созданию связи между основным сервисом и его таймерами, поскольку systemd ожидает конкретные имена файлов устройств во время активации.
Пример
Для устранения этой проблемы можно изменить конфигурацию, переместив связь на уровень директивы WantedBy
, таким образом:
[Unit]
Description=Does something cool
Documentation=man:foo(1)
[Service]
Type=forking
ExecStart=/usr/bin/foo %i
PIDFile=%t/foo/foo.pid
StandardOutput=journal
[Install]
WantedBy=network-online.target bar1@%i.timer bar2@%i.timer
Этот подход позволяет systemd корректно интерпретировать спецификатор %i
, когда вы используете команду systemctl enable
.
Применение
Примените этот метод, выполнив следующие шаги:
-
Измените файл вашего системного юнита, как указано выше.
-
Вначале активируйте необходимые таймеры с помощью команд:
systemctl enable bar1@<instance>.timer systemctl enable bar2@<instance>.timer
-
Затем активируйте основной сервис, что автоматически активирует и таймеры:
systemctl enable bar@<instance>.service
Таким образом, при активации основного сервиса будут автоматически активированы и таймеры. Этот способ является обоснованным обходным путем для текущего поведения systemd и позволяет достичь требуемой функциональности, минимально изменяя изначальные конфигурации системы.