Вопрос или проблема
У меня есть файл юнита myservice.service
, который выглядит следующим образом:
...
ExecStartPre=prehook.sh
...
ExecStart=myapp
ExecStopPost=posthook.sh
...
prehook.sh выполняет различные действия, и, среди прочего, он заменяет файл юнита, если он отличается от локальной копии, и вызывает daemon-reload
:
...
# Сравнить файлы
if cmp -s "$SYSTEMD_FILE" "$LOCAL_FILE"; then
echo "Файлы юнита идентичны. Обновление не требуется."
else
echo "Файлы юнита различаются. Обновление файла юнита systemd."
# Копировать локальную версию в /lib/systemd/system
cp "$LOCAL_FILE" "$SYSTEMD_FILE"
systemctl daemon-reload
echo "Конфигурация systemd перезагружена"
fi
# Продолжить с чем-то другим
...
Локальная копия отличается от в настоящее время загруженного файла юнита в строке ExecStart
:
...
ExecStart=myappModified
...
Поведение, которого я ожидал бы, заключается в том, что, если файл юнита изменяется во время ExecStartPre
, то daemon-reload влияет только на последующие вызовы systemctl start myservice
, но не на текущий.
Удивительно, но systemd, похоже, перезагружает “на лету” строку ExecStart
, уважая то, что указано в локальной копии.
Хотя это удобное поведение для скрипта prehook, я не могу найти никаких подтверждений этому в документации. Я что-то упускаю?
Версия systemd — 240.
Ответ или решение
Понимание поведения daemon-reload
в ExecStartPre
в systemd
Система инициализации systemd предоставляет пользователям серьезные возможности управления службами, в том числе возможность выполнения дополнительных действий перед стартом самой службы через директиву ExecStartPre
. В вашем случае, вы задали вопрос, касающийся поведения daemon-reload
при изменении файла юнита в процессе выполнения ExecStartPre
. Давайте рассмотрим этот вопрос более детально.
Как работает ExecStartPre
?
ExecStartPre
— это директива, которая позволяет выполнять указанный сценарий или команду перед началом основной службы, указанной в ExecStart
. Это поведение идеально подходит для задач подготовки, таких как инициализация окружения, проверка зависимостей или, как в вашем случае, обновление конфигурации.
Поведение daemon-reload
Ваша проблема заключается в том, что вы обнаружили, что после исполнения команды daemon-reload
в ExecStartPre
, systemd, похоже, применяет изменения на лету, и вместо ожидаемого поведения, при котором изменения затрагивают только будущие запуски, ваша служба начинает использовать обновленное значение ExecStart
.
На самом деле, это поведение systemd имеет свои особенности, которые не всегда явно указаны в документации. В версиях systemd начиная с 239, введены улучшения для управления юнитами и обработки изменений конфигурации. Установки, сделанные с помощью daemon-reload
в процессе работы юнита, могут приводит к тому, что systemd будет повторно оценивать конфигурацию юната, если это необходимо.
Почему это происходит?
Когда вы выполняете команду daemon-reload
, systemd пересобирает внутреннее состояние, включая все параметры, которые могут быть изменены во время работы системы. Это значит, что любые изменения, сделанные в файле юнита, даже в процессе выполнения ExecStartPre
, активируются непосредственно для текущего процесса. Таким образом, если изменения в конфигурации касаются параметров запуска (например, ExecStart
), systemd применит эти изменения немедленно.
Могу ли я управлять этим поведением?
На данный момент, официального метода для предотвращения этого поведения в systemd не существует. Однако, вы можете рассмотреть следующие подходы:
-
Изменение логики вашего скрипта: Возможно, имеет смысл изменить способ определения и применения обновлений файла юнита. Например, вы можете вынести часть логики, отвечающей за обновление юнита, в отдельный исследовательский скрипт, который будет выполнен отдельно от
ExecStartPre
. -
Доступ к версии юнита: Вместо обновления юнита внутри
ExecStartPre
, можно периодически проверять текущую версию юнита перед его запуском.
Заключение
Вы обнаружили, что systemd обрабатывает изменения файлов юнитов в процессе добавления жара моментально после daemon-reload
с учетом текущего запущенного процесса. Это поведение, хотя и может быть неожиданным, продуктивно для обеспечения актуальности конфигураций и улучшения управляемости сервисов.
Если вам необходимо более детальное разъяснение или практическая помощь, не стесняйтесь задавать дополнительные вопросы. Важно учитывать, что с обновлениями системы могут появляться новые функции и экспериментальные усовершенствования, способствующие решению аналогичных задач.