Я пытаюсь иметь несколько изображений VirtualBox, запускаются автоматически на начальной загрузке и быть завершением работы правильно на завершении работы хоста перед выключением. У меня есть сценарий удара, /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
существует запись в системном журнале, который указывает Stopped VirtualBox Control
но это ничего не делает.
Я - общий новичок к systemd. Я недавно обновил это поле Ubuntu до 16,04. Я вполне уверен существует простое объяснение этого поведения, что я просто не вижу.
Спасибо!
Обновление на основе предложения Mark's:
Я подтвердил использование синтаксиса 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.
Ваш systemd
синтаксис правилен. Ваша проблема в другом месте.
Первый, можно подтвердить, что сам синтаксис правилен с:
systemd-analyze verify /path/to/your/vmctl.service
1112-секундный, попытайтесь заменить этими строками:
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
Установка Type по умолчанию для Сервисной единицы является Type=simple, который используется, когда процесс, настроенный с ExecStart =, является основным процессом сервиса. Такая единица будет ожидать до процесса, указанного возвратами ExecStart, затем деактивироваться путем выполнения процесса, указанного ExecStop. В Вашем случае это произойдет, как только виртуальные машины были запущены (не, что Вы хотите).
Type=forking используется, когда процесс, указанный ExecStart, как ожидают, выйдет после того, как запуск будет завершен, в то время как его дочерний процесс (процессы) продолжается (s) для выполнения в фоновом режиме. Это - поведение традиционных демонов UNIX и рекомендуемого выбора в Вашем случае. Процесс, указанный ExecStop, будет работать в случае, если сервис отказывает, или на “systemctl останавливают 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
Как другие упомянули, проблема - это vmctl.sh
сразу выходы. Вопреки ответу @Christophe разветвление не будет работать, скорее всего, как vmctl.sh
вероятно, не разветвляется. То, в чем Вы нуждаетесь, является a oneshot
сервис, с RemainAfterExit=true
. Если Вы просто изменяете его на oneshot
, Вы получите то же самое поведение. RemainAfterExit
часть говорит это это даже после ExecStart
выходы, сервис нужно все еще рассмотреть, работая, таким образом, он не должен работать ExecStop
(s).