systemd игнорирует ExecStop в файле unit, запускает его как часть ExecStart

Я пытаюсь, чтобы несколько изображений VirtualBox запускались автоматически при загрузке и корректно завершались при отключении хоста перед отключением питания. У меня есть сценарий bash, /usr/local/bin/vmctl.sh, который обрабатывает запуск и остановку гостевых изображений с помощью вызовов VBoxManage. Стартовый вызов очень прост - он просто просматривает список изображений, а вызовы VBoxManage startvm --type headless "<imgname>" затем выходят из 0. Стоп-звонок циклически перебирается по списку и вызывает VBoxManage controlvm "<imgname>" acpipowerbutton, затем цикл до тех пор, пока VBoxManage list runningvms не вернет пустой список ИЛИ пройдет 60 секунд прежде чем он выйдет 0. Запуск сценария из командной строки работает отлично.

Я установил единичный файл в /lib/systemd/system/vmctl.service:

[Unit] Description=VirtualBox Control After=virtualbox.service [Service] ExecStart=/usr/local/bin/vmctl.sh start ExecStop=/usr/local/bin/vmctl.sh stop [Install] WantedBy=multi-user.target

Когда я запускаю systemctl start vmctl.service , он вызывает и стартовую, и стоп-линию. Когда я вызываю systemctl stop vmctl.service, в syslog есть запись, в которой указано Stopped VirtualBox Control, но она ничего не делает.

Я полный неофит для systemd. Недавно я обновил этот Ubuntu до 16.04.

Спасибо!

Обновление, основанное на предположении Марка:

! d6]

Я подтвердил синтаксис с помощью systemd-analyze verify /etc/systemd/system/vmctl.service (после перемещения файла там - спасибо за подсказку). Затем я изменил ExecStart и ExecStop, как вы предположили, выполнил systemctl daemon-reload и все еще видит то же поведение. Журнал показывает оба исполнения при вызове systemctl start vmctl, но ни при запуске systemctl stop vmctl:

# journalctl -u vmctl | tail . . . Apr 06 19:28:18 macmi10-builder systemd[1]: Started VirtualBox Control. Apr 06 19:28:18 macmi10-builder echo[13901]: I started Apr 06 19:28:18 macmi10-builder echo[13904]: I stopped Apr 06 19:28:33 macmi10-builder systemd[1]: Stopped VirtualBox Control.
1
задан 7 April 2017 в 20:06

9 ответов

Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.

Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».

Таким образом, ваш файл устройства должен быть:

[Unit] Description=VirtualBox Control After=virtualbox.service [Service] Type=forking ExecStart=/usr/local/bin/vmctl.sh start ExecStop=/usr/local/bin/vmctl.sh stop [Install] WantedBy=multi-user.target
0
ответ дан 18 July 2018 в 15:27

Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).

2
ответ дан 18 July 2018 в 15:27

Ваш синтаксис systemd верен. Ваша проблема в другом месте.

Сначала вы можете подтвердить, что сам синтаксис правильный:

systemd-analyze verify /path/to/your/vmctl.service

Во-вторых, попробуйте подставить эти строки:

ExecStart=/bin/echo "I started" ExecStop=/bin/echo "I stopped"

После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.

Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system

3
ответ дан 18 July 2018 в 15:27

Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.

Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».

Таким образом, ваш файл устройства должен быть:

[Unit] Description=VirtualBox Control After=virtualbox.service [Service] Type=forking ExecStart=/usr/local/bin/vmctl.sh start ExecStop=/usr/local/bin/vmctl.sh stop [Install] WantedBy=multi-user.target
0
ответ дан 24 July 2018 в 20:38
  • 1
    Скрипт vmctl.sh не является демоном - это контроллер и, скорее всего, не вилок. – Duncan X Simpson 22 January 2018 в 19:01

Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).

2
ответ дан 24 July 2018 в 20:38
  • 1
    omg lifesaver, onehot отлично подходит для обслуживания vncserver: D спасибо. – erm3nda 31 March 2018 в 03:03

Ваш синтаксис systemd верен. Ваша проблема в другом месте.

Сначала вы можете подтвердить, что сам синтаксис правильный:

systemd-analyze verify /path/to/your/vmctl.service

Во-вторых, попробуйте подставить эти строки:

ExecStart=/bin/echo "I started" ExecStop=/bin/echo "I stopped"

После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.

Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system

3
ответ дан 24 July 2018 в 20:38
  • 1
    После замены этих команд на простой или forking-сервис отражается то же поведение. Для простого эха выхода ExecStart выходит, поэтому он вызывает ExecStop. Для разветвления бегущих дочерних процессов из эха ExecStart нет, и как таковой он вызывает ExecStop. – Duncan X Simpson 22 January 2018 в 19:05

Параметр Тип по умолчанию для Единицы обслуживания - Type = simple, который используется, когда процесс, сконфигурированный с помощью ExecStart =, является основным процессом службы. Такой блок будет ожидать, пока процесс, указанный ExecStart, не будет возвращен, затем деактивируйте, запустив процесс, указанный ExecStop.

Тип = simple используется, когда ожидается, что процесс, указанный ExecStart, ожидается, будет выполняться, как только будут запущены виртуальные машины (не то, что вы хотите). для выхода после завершения запуска, а его дочерние процессы (ы) продолжаются (ы) для запуска в фоновом режиме. Это поведение традиционных демонов UNIX и рекомендуемый выбор в вашем случае. Процесс, указанный ExecStop, будет выполняться в случае сбоя службы или команды «systemctl stop vmctl».

Таким образом, ваш файл устройства должен быть:

[Unit] Description=VirtualBox Control After=virtualbox.service [Service] Type=forking ExecStart=/usr/local/bin/vmctl.sh start ExecStop=/usr/local/bin/vmctl.sh stop [Install] WantedBy=multi-user.target
0
ответ дан 31 July 2018 в 23:40
  • 1
    Скрипт vmctl.sh не является демоном - это контроллер и, скорее всего, не вилок. – Duncan X Simpson 22 January 2018 в 19:01

Как уже упоминалось, проблема в том, что vmctl.sh сразу же выходит. В отличие от ответа Кристофа, разветвление не будет работать, скорее всего, поскольку vmctl.sh, вероятно, не развивает. Вам нужна услуга oneshot, с RemainAfterExit=true. Если вы просто измените его на oneshot, вы получите то же самое поведение. Часть RemainAfterExit сообщает, что даже после выхода ExecStart сервис все равно следует считать запущенным, поэтому он не должен запускать ExecStop (s).

2
ответ дан 31 July 2018 в 23:40
  • 1
    omg lifesaver, onehot отлично подходит для обслуживания vncserver: D спасибо. – erm3nda 31 March 2018 в 03:03

Ваш синтаксис systemd верен. Ваша проблема в другом месте.

Сначала вы можете подтвердить, что сам синтаксис правильный:

systemd-analyze verify /path/to/your/vmctl.service

Во-вторых, попробуйте подставить эти строки:

ExecStart=/bin/echo "I started" ExecStop=/bin/echo "I stopped"

После запуска systemctl start vmctl или systemctl stop vmctl используйте journalctl -u vmctl для проверки журналов. Я ожидаю, что вы подтвердите systemd выполнили правильные команды.

Также /lib/systemd/system предназначен для места для пакетов для управления файлами systemd. Файлы, которые изменяются и управляются человеком, предназначены для входа в /etc/systemd/system

3
ответ дан 31 July 2018 в 23:40
  • 1
    После замены этих команд на простой или forking-сервис отражается то же поведение. Для простого эха выхода ExecStart выходит, поэтому он вызывает ExecStop. Для разветвления бегущих дочерних процессов из эха ExecStart нет, и как таковой он вызывает ExecStop. – Duncan X Simpson 22 January 2018 в 19:05

Другие вопросы по тегам:

Похожие вопросы: