Вопрос или проблема
На виртуальной машине VBox у меня есть сервис, который отслеживает изменения состояния ip
, например, при подключении к VPN. Работающий скрипт требует доступа к пути в общей папке VBox, смонтированной в /mnt/host
. Предполагаю, что эта точка монтирования отображается в списке сервисов systemd как mnt-host.mount
.
systemctl list-units | grep mount
...
mnt-host.mount loaded active mounted mnt-host.mount
...
В определении сервиса я прошу systemd ждать этой точки монтирования перед запуском моего сервиса сети:
[Unit]
Description=monitor network
After=mnt-host.mount
[Service]
ExecStart=/usr/local/bin/network-monitor.sh
[Install]
WantedBy=default.target
Однако это не работает. Запуск сервиса не удается, потому что требуемая директория еще не смонтирована. Как только загрузка ВМ завершена, я могу перезапустить сервис, и все работает хорошо, но я хочу, чтобы сервис запускался без моего вмешательства.
Самый простой способ обойти эту проблему — настроить сервис systemd на автоматический перезапуск в случае ошибки, пока он не сможет действительно найти общую папку:
[Service]
Restart=on-failure
RestartSec=5
В качестве альтернативы, если у вас есть контроль над bash-скриптом, который будет запускаться сервисом systemd, вы могли бы сделать следующее:
# Не продолжайте, пока файл не станет доступным (замените $SHARED_PATH при необходимости)
while [ ! -f $SHARED_PATH ]
do
sleep 2
done
Ответ или решение
Для решения проблемы с тем, что служба systemd не запускается до монтирования общей папки VirtualBox, важно разобраться в некоторых деталях процесса загрузки и зависимостях systemd.
Шаг 1: Понимание зависимости от mnt-host.mount
Ваша текущая конфигурация указывает, что служба должна начинаться после mnt-host.mount
, через использование директивы After=mnt-host.mount
. Тем не менее, возможны случаи, когда несмотря на это, монтирование может быть завершено некорректно или нужное состояние не достигается до запуска службы мониторинга сети.
Шаг 2: Переработка файла службы
Опция перезапуска службы
Использование директивы Restart=on-failure
в секции [Service]
является хорошим первым шагом. Это обеспечивает автоматический перезапуск службы в случае ошибки, давая системе время дождаться корректного монтирования общей папки.
[Service]
Restart=on-failure
RestartSec=5
Проверка в bash-скрипте
Если у вас есть доступ к редактированию вашего bash-скрипта (network-monitor.sh
), включите в него логику проверки доступности директории:
# Не продолжать выполнение, пока директория недоступна (замените $SHARED_PATH правильным путём)
SHARED_PATH="/mnt/host/your-directory" # Убедитесь, что этот путь правильный
while [ ! -d $SHARED_PATH ]
do
sleep 2
done
Шаг 3: Доработка зависимости в systemd
Для гарантий того, что mnt-host.mount
монтируется должным образом до запуска службы, можно использовать дополнительную директиву Requires=
в секции [Unit]
:
[Unit]
Description=monitor network
After=mnt-host.mount
Requires=mnt-host.mount
Заключение
Таким образом, использования директив After
и Requires
, наряду с механизмом Restart=on-failure
, а также добавление проверки доступности папки в вашем скрипте, поможет гарантировать, что служба запускается корректно после монтирования требуемой директории. Эффективное использование зависимостей и корректная обработка потенциальных отказов системы обеспечивают надежность и автоматизацию без необходимости ручного вмешательства.