Вопрос или проблема
У меня есть 2 systemd сервиса.
a.service
b.service
b зависит от a, но я не хочу явно указывать зависимость в файле b.service.
Вместо этого я жду сигнал
org.freedesktop.DBus.Properties.PropertiesChanged
от a.service, когда он запускается при загрузке в коде b.c и опрашиваю, пока не получу
этот сигнал для его активации.
sd_ret = sd_bus_match_signal
(
bus,
NULL,
DESTINATION,
A_PATH,
INTERFACE,
"PropertiesChanged",
sd_callback,
NULL
);
А затем использую poll для ожидания сигнала от dbusfd.
Я провел следующий эксперимент:
Эксперимент 1:
ШАГ 1:
systemctl mask a.service
systemctl mask b.service
ШАГ 2:
перезагрузка
ШАГ 3:
systemctl unmask a.service
systemctl unmask b.service
ШАГ 4:
запустить бинарный файл ‘b’
./b
ШАГ 4:
systemctl start a.service
Наблюдение:
b.service может поймать сигнал:
Сработало совпадение сигнала! destination=(null) interface=org.freedesktop.DBus.Properties member=PropertiesChanged path=/org/freedesktop/systemd1/unit/a2eservice
Начинаю опрос
Сработало совпадение сигнала! destination=(null) interface=org.freedesktop.DBus.Properties member=PropertiesChanged path=/org/freedesktop/systemd1/unit/a_2eservice
Имя свойства: ActiveState
Обновленное ActiveState: active
Сервис a теперь активен.
Но в Эксперименте 2
Оба сервиса размаскированы при загрузке.
При загрузке a.service, похоже, не испускает сигнал PropertiesChanged.
Поэтому хотел бы узнать, одинаково ли поведение сервиса a во время загрузки и после нее,
и отправляет ли сервис a сигнал PropertiesChanged во время загрузки?
Ответ или решение
Вопрос о том, отправляет ли системное приложение службы systemd сигнал org.freedesktop.DBus.Properties.PropertiesChanged
при загрузке, имеет значительный интерес для тех, кто работает над оркестрацией системных процессов в Linux среде. Ваша ситуация затрагивает два systemd сервиса: a.service
и b.service
, где b.service
зависит от a.service
без явного указания зависимости в конфигурации сервиса. Вы полагаетесь на сигнал PropertiesChanged
, чтобы разблокировать запуск b.service
, когда a.service
становится активной.
Наблюдения и Эксперименты
Эксперимент 1
Ваш первый эксперимент демонстрирует успешное получение сигнала PropertiesChanged
после выполнения следующих действий:
- Маскирование сервисов
a.service
иb.service
. - Перезагрузка системы.
- Размаскирование и запуск
b
бинарного файла до стартаa.service
. - Старт
a.service
. В этом случае,b.service
корректно получает сигнал и обрабатывает его.
Эксперимент 2
Второй эксперимент показывает, что когда оба сервиса размаскированы и активируются при загрузке, b.service
не удается получить сигнал PropertiesChanged
от a.service
. Это указывает на то, что при запуске системы сигнал может не быть отправлен так, как ожидалось в вашем флоу.
Анализ
Во время загрузки системы порядок запуска инициализаций может влиять на отправку сигналов в D-Bus интерфейсе. Основными проблемами могут быть следующие:
-
Конкуренция за ресурсы: Когда система запускается, множество сервисов может одновременно конкурировать за системные ресурсы, что способно нарушить обычный порядок обработки сигналов.
-
Сохранение состояния: В контексте systemd сигнал
PropertiesChanged
может не отправляться, если состояние сервиса не изменилось с точки зрения D-Bus API. Если сервис загружается сразу в ожидаемое состояние, сигнал может не проявиться. -
Инициализация D-Bus: На момент, когда ваш сервис полагается на сигнал от
a.service
, D-Bus может еще не быть готов или обслуживать очередь других запросов.
Рекомендации
Чтобы убедиться, что ваша архитектура правильно обрабатывает запуск сервисов при загрузке системы, рассмотрите следующие подходы:
-
Добавьте контрольный механизм: Интеграция более надежного механизма синхронизации, такого как использование таймеров или ручной ввод связей между сервисами, может повысить уверенность в корректной инициализации
a.service
передb.service
. -
Журналирование и отладка: Проверьте журналы systemd и D-Bus для выявления всех возникающих сообщений об ошибках или предупреждений, указывающих на проблемы с сигналами.
-
Изменение логики запуска: Если целевое состояние
b.service
всегда зависит отa.service
, обдумайте возможность явного указания зависимости в файле службы. Вы можете использовать такие директивы, какAfter=
, чтобы указать порядок запуска.
Заключение: Поведение служб systemd при загрузке системы может различаться из-за логики и синхронизации процессов. Развивая архитектуру системы с учетом вышеупомянутых рекомендаций, вы обеспечите более надежное управление запуском и зависимостями сервисов.