CentOS 7 – Systemctl Hangs When Starting Headless Virtual Machine

centosservicesvirtualbox

I'm not entirely sure if what I'm trying to do can work. I would like to run a vbox virtual machine as a service and have it enabled on startup. Here is my .service script:

[Unit]
Description=Virtualbox Headless VM
Wants=network-online.target
After=network-online.target

[Service]
Type=forking
ExecStart=/usr/bin/VBoxHeadless -s vbox_uuid
ExecStop=/usr/bin/VBoxManage controlvm vbox_uuid poweroff
User=myuser

[Install]
WantedBy=muti-user.target

When I try to start this normally my cli hangs and doesn't fork the process. Does anybody have any thoughts/ideas/suggestions?

systemctl status gives me this:

Jun 20 07:17:07 localhost.localdomain systemd[1]: Starting Virtualbox Headless VM...
Jun 20 07:17:09 localhost.localdomain pulseaudio[4143]: [pulseaudio] socket-server.c: bind(): Address already in use
Jun 20 07:17:09 localhost.localdomain pulseaudio[4143]: [pulseaudio] module.c: Failed to load module "module-esound-protocol-unix" (argument: ""): initialization failed.
Jun 20 07:17:09 localhost.localdomain pulseaudio[4143]: [pulseaudio] main.c: Module load failed.
Jun 20 07:17:09 localhost.localdomain pulseaudio[4143]: [pulseaudio] main.c: Failed to initialize daemon.
Jun 20 07:17:09 localhost.localdomain pulseaudio[4140]: [pulseaudio] main.c: Daemon startup failed.
Jun 20 07:18:37 localhost.localdomain systemd[1]: vboxmachines.service operation timed out. Terminating.
Jun 20 07:18:37 localhost.localdomain systemd[1]: Failed to start Virtualbox Headless VM.
Jun 20 07:18:37 localhost.localdomain systemd[1]: Unit vboxmachines.service entered failed state.

Thanks!

Best Answer

You have a readiness protocol mismatch.

The Type of a service is important. That setting denotes what readiness protocol systemd expects the service to speak. A simple service is assumed to be immediately ready. A forking service is taken to be ready after its initial process forks a child and then exits. A dbus service is taken to be ready when a server appears on the Desktop Bus. And so forth.

If you don't get the readiness protocol declared in the service unit to match what the service does, then things go awry. Readiness protocol mismatches cause services not to start correctly, or (more usually) to be (mis-)diagnosed by systemd as failing. When a service is seen as failing to start because the readiness protocol never triggers systemd ensures that every orphaned additional process of the service that might have been left running as part of the failure (from its point of view) is killed in order to bring the service properly back to the inactive state.

VBoxHeadless does not (uselessly) fork and exit. The VirtualBox doco states this explicitly. So the correct setting in your service unit is Type=simple.

By the way, the rest of us can trace the parentage of your service unit to this anonymous post to an ArchLinux forum probably via a follow-up post on StackOverflow, because you've copied the very spelling mistake that the anonymous person made there. The correct spelling is WantedBy=multi-user.target. That went two and a half years (and 2170 views) without being spotted. It would no doubt have been your next question, too.

The template service unit from the Arch Linux wiki, which parameterizes on the UUID of the virtual machine, is the way to go, here.

Further reading

Related Question