Назад | Перейти на главную страницу

systemctl после того, как зависимость не указана (и, вероятно, не работает)

Я хочу перенести службу gammu-smsd на mariadb, поэтому я отредактировал службу systemctl edit --full gammu-smsd.service - Я добавил mariadb.service в строке После.

[Unit]
Description=SMS daemon for Gammu
Documentation=man:gammu-smsd(1)
After=mariadb.service postgresql.service network-online.target

Проверил, что mariadb существует: systemctl list-units --type=service:

mariadb.service loaded active running MariaDB 10.3.15 database server

Но нигде новой зависимости не вижу:

systemctl list-dependencies gammu-smsd.service 
gammu-smsd.service
● ├─system.slice
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─fake-hwclock.service
●   ├─keyboard-setup.service
●   ├─kmod-static-nodes.service
●   ├─proc-sys-fs-binfmt_misc.automount
●   ├─resolvconf.service
●   ├─sys-fs-fuse-connections.mount
●   ├─sys-kernel-config.mount
●   ├─sys-kernel-debug.mount
●   ├─systemd-ask-password-console.path
●   ├─systemd-binfmt.service
●   ├─systemd-hwdb-update.service
●   ├─systemd-journal-flush.service
●   ├─systemd-journald.service
●   ├─systemd-machine-id-commit.service
●   ├─systemd-modules-load.service
●   ├─systemd-random-seed.service
●   ├─systemd-sysctl.service
●   ├─systemd-sysusers.service
●   ├─systemd-tmpfiles-setup-dev.service
●   ├─systemd-tmpfiles-setup.service
●   ├─systemd-udev-trigger.service
●   ├─systemd-udevd.service
●   ├─systemd-update-utmp.service
●   ├─cryptsetup.target
●   ├─local-fs.target
●   │ ├─-.mount
●   │ ├─boot.mount
●   │ ├─DietPi.mount
●   │ ├─systemd-fsck-root.service
●   │ ├─systemd-remount-fs.service
●   │ ├─tmp.mount
●   │ └─var-log.mount
●   └─swap.target
●     └─var-swap.swap

Кроме того, gammu-smsd запускается до готовности maria DB. Может ли кто-нибудь указать, что я делаю неправильно? Спасибо!

After= только гарантирует, что служба запускается после другой службы, если обе услуги активированы.

Если вы хотите иметь реальную зависимость от mariadb, вы должны использовать Requires= или Wants=. Это определяет следующее поведение:

  • если вы активируете гамму-smsd, Мариадб также будет активирован
  • если гамму-smsd начинается и Мариадб не работает, он будет запущен за вас
  • если Мариадб останавливается и гамму-smsd работает, он будет остановлен для вас

Обычно вы все равно захотите использовать After=, так как Require= и Wants= не обеспечивайте порядок. Если вы используете только Requires= или Wants= гамму-smsd может быть запущен параллельно или раньше Мариадб.

Если вы используете Require= и After= гамму-smsd не начнется, если Мариадб не запускается. В то время какWants= все равно получит гамму-smsd началось, если Мариадб не запускается. Автор RPM gammu-smsd, вероятно, поместил туда After для mariadb и postgresql, чтобы вы могли выбирать между одним, обоими или ни одним из них, активировав соответствующие службы.

На практике вам не обязательно добавлять Requires= или Wants= линия к гамму-smsd конфигурация. Просто убедитесь, что Мариадб активирован.

Вероятно, ваша проблема в том, что mariadb успешно перешел в рабочее состояние, но все еще не готов принимать соединения. По крайней мере, на RHEL mariadb настроен как Type=simple это означает, что он немедленно переходит в рабочее состояние, как только запускается процесс mariadb, даже если он еще не принимает соединения.

Один простой и хитрый способ справиться с этим - просто добавить небольшую задержку к началу гамму-smsd с участием:

ExecStartPre=/bin/sleep 30

Более продвинутый способ - использовать что-то вроде этого: https://github.com/vishnubob/wait-for-it.

Для получения дополнительной информации вы должны прочитать страницы руководства для systemd.unit и systemd.service.

Тип =

Настраивает тип запуска процесса для этой сервисной единицы. Один из простых, exec, forking, oneshot, dbus, notify или idle:

Если установлено значение simple (по умолчанию, если указано ExecStart =, но не указано ни Type =, ни BusName =), диспетчер служб будет считать, что модуль запущен сразу после того, как основной процесс службы был разветвлен. Ожидается, что процесс, сконфигурированный с ExecStart =, является основным процессом службы. В этом режиме, если процесс предлагает функциональные возможности другим процессам в системе, его каналы связи должны быть установлены до запуска службы (например, сокеты, установленные systemd, через активацию сокета), поскольку менеджер службы немедленно приступит к выполнению следующих действий. -up единиц сразу после создания основного процесса службы и перед выполнением двоичного файла службы. Обратите внимание, что это означает, что командные строки systemctl start для простых служб будут сообщать об успешном выполнении, даже если двоичный файл службы не может быть успешно запущен (например, потому что выбранный User = не существует или двоичный файл службы отсутствует).

Требуется =

Настраивает зависимости требований от других модулей. Если этот отряд активируется, перечисленные здесь юниты также будут активированы. Если один из других модулей не активируется, и установлена ​​зависимость упорядочения After = для отказавшего модуля, этот модуль не будет запущен. Кроме того, с указанием After = или без него, этот модуль будет остановлен, если один из других модулей будет остановлен явно. Эта опция может быть указана более одного раза или несколько единиц, разделенных пробелами, могут быть указаны в одной опции, и в этом случае будут созданы зависимости требований для всех перечисленных имен. Обратите внимание, что зависимости требований не влияют на порядок, в котором службы запускаются или останавливаются. Это должно быть настроено независимо с опциями After = или Before =. Если для модуля foo.service требуется модуль bar.service, настроенный с помощью Requires =, а порядок не настроен с помощью After = или Before =, то оба модуля будут запущены одновременно и без какой-либо задержки между ними, если foo.service активирован. Часто лучше использовать Wants = вместо Requires =, чтобы получить более надежную систему при работе с отказавшими службами.

Обратите внимание, что этот тип зависимости не означает, что другой модуль всегда должен находиться в активном состоянии, когда этот модуль работает. В частности: неудачные проверки условий (такие как ConditionPathExists =, ConditionPathIsSymbolicLink =,… - см. Ниже) не приводят к сбою начального задания модуля с зависимостью Requires = от него. Кроме того, некоторые типы модулей могут деактивироваться сами по себе (например, процесс обслуживания может решить завершиться без ошибок, или устройство может быть отключено пользователем), что не распространяется на модули, имеющие зависимость Requires =. Используйте тип зависимости BindsTo = вместе с After =, чтобы гарантировать, что объект никогда не может быть в активном состоянии без определенного другого объекта, также в активном состоянии (см. Ниже).

Обратите внимание, что зависимости этого типа также могут быть настроены вне файла конфигурации модуля, добавив символическую ссылку на каталог .requires /, сопровождающий файл модуля. Подробнее см. Выше.

Хочет =

Более слабая версия Requires =. Блоки, перечисленные в этой опции, будут запущены, если блок настройки. Однако, если перечисленные единицы не запускаются или не могут быть добавлены к транзакции, это не влияет на действительность транзакции в целом. Это рекомендуемый способ связать запуск одного блока с запуском другого блока.

Обратите внимание, что зависимости этого типа также могут быть настроены вне файла конфигурации модуля путем добавления символических ссылок в каталог .wants /, сопровождающий файл модуля. Подробнее см. Выше.

До =, После =

Эти две настройки предполагают список имен единиц, разделенных пробелами. Они настраивают зависимости порядка между единицами. Если модуль foo.service содержит параметр Before = bar.service и оба модуля запускаются, запуск bar.service откладывается до завершения запуска foo.service. Обратите внимание, что этот параметр не зависит и ортогонален зависимостям требований, настроенным с помощью Requires =, Wants = или BindsTo =. Распространенным шаблоном является включение имени модуля в параметры After = и Requires =, и в этом случае указанный модуль будет запущен раньше модуля, настроенного с этими параметрами. Этот параметр может быть указан более одного раза, и в этом случае будут созданы зависимости упорядочения для всех перечисленных имен. After = является обратным значению Before =, то есть в то время как After = гарантирует, что настроенный модуль запускается после того, как указанный модуль завершил запуск, Before = гарантирует обратное, что настроенный модуль полностью запускается до того, как указанный модуль запускается. Обратите внимание, что при отключении двух блоков с зависимостью порядка их включения применяется обратный порядку запуска. то есть, если блок настроен с помощью After = на другом блоке, первый останавливается раньше второго, если оба отключены. Для двух блоков с какой-либо зависимостью порядка их выполнения, если один блок выключен, а другой запущен, отключение назначается перед запуском. В этом случае не имеет значения, является ли зависимость упорядочения After = или Before =. Также не имеет значения, какой из двух выключен, если один выключен, а другой запущен. Во всех случаях отключение заказывается перед запуском. Если два блока не имеют зависимостей по порядку между собой, они выключаются или запускаются одновременно, и заказ не производится. Это зависит от типа установки, когда именно установка завершила запуск. Наиболее важно то, что для сервисных единиц запуск считается завершенным для целей Before = / After =, когда все его настроенные команды запуска были вызваны, и они либо завершились неудачно, либо сообщили об успешном запуске.

ExecStartPre =, ExecStartPost =

Дополнительные команды, которые выполняются до или после команды в ExecStart = соответственно. Синтаксис такой же, как и для ExecStart =, за исключением того, что разрешено несколько командных строк, и команды выполняются одна за другой, последовательно.

Если какая-либо из этих команд (без префикса «-») завершается неудачно, остальные не выполняются, и модуль считается неисправным.

Команды ExecStart = запускаются только после того, как все команды ExecStartPre =, которые не имеют префикса "-", успешно завершаются.

Команды ExecStartPost = запускаются только после того, как команды, указанные в ExecStart =, были успешно вызваны, как определено Type = (т.е. процесс был запущен для Type = simple или Type = idle, последний ExecStart = процесс завершился успешно для Type = oneshot , начальный процесс успешно завершился для Type = forking, "READY = 1" отправляется для Type = notify, или BusName = было взято для Type = dbus).

Обратите внимание, что ExecStartPre = не может использоваться для запуска длительно выполняющихся процессов. Все процессы, разветвленные процессами, вызванными через ExecStartPre =, будут уничтожены до запуска следующего служебного процесса.

Обратите внимание: если какая-либо из команд, указанных в ExecStartPre =, ExecStart = или ExecStartPost =, завершится ошибкой (и не имеет префикса «-», см. Выше) или истечет время ожидания до того, как служба будет полностью запущена, выполнение продолжается с командами, указанными в ExecStopPost = , команды в ExecStop = пропускаются.

Вы должны добавить --after возможность увидеть зависимость. В этом случае ваша команда будет выглядеть так:

systemctl list-dependencies --after gammu-smsd.service