У нас есть сервер (гипервизор), на котором размещено множество виртуальных машин, контролируемых libvirt. libvirt предоставляет виртуальную сеть для связи между виртуальными машинами и гипервизором. Эта виртуальная сеть устанавливается во время выполнения libvirtd.service
и называется sys-devices-virtual-net-virbr1.device
.
Несколько служб, работающих на гипервизоре, должны быть привязаны к этой виртуальной сети, например, IMAP, база данных и т. д.
Проблема, с которой мы сталкиваемся, заключается в том, что службы, работающие на гипервизоре, запускаются systemd до настройки виртуальной сети, поэтому запуск служб не удался. Текущий порядок запуска показан на этом графике:
график порядка запуска systemd
Для таких случаев существуют директивы systemd, например:
After=
Required=
Wants=
и так далее. Но в моем случае они не помогают. Насколько я понял, причина в том, что sys-devices-virtual-net-virbr1.device
создается libvirtd.service
динамически во время выполнения и неизвестен systemd при запуске системы. Поэтому зависимость не может быть разрешена при запуске systemd, поскольку sys-devices-virtual-net-virbr1.device
сетевой интерфейс неизвестен.
Предоставляет ли systemd методы решения подобных проблем?
Любая подсказка приветствуется. Спасибо.
решение1
Вы можете настроить сервисный модуль как зависимый от модуля устройства, даже если этот модуль устройства явно не определен в другом модуле (например, он получен из udev).
[Unit]
BindsTo=sys-devices-virtual-net-virbr1.device
After=sys-devices-virtual-net-virbr1.device
Как вы можете видеть в man systemd.unit
Привязывает к=
Configures requirement dependencies, very similar in style to Requires=. However, this dependency type is stronger: in addition to the effect of Requires= it declares that if the unit bound to is stopped, this unit will be stopped too.
When used in conjunction with After= on the same unit the behaviour of BindsTo= is even stronger. In this case, the unit bound to strictly has to be in active state for this unit to also be in active state