During VB updates, it's required to shutdown all guests. I also wanted to do that in a single command; not having to type "stop" 12 times.
We need to create two unit files: The main "all" service:
Code: Select all
# cat /etc/systemd/system/virtualbox-leon-all.service | grep -v "^#"
[Unit]
Description=VirtualBox Leon-all machine ...
Requires=ssh.service
After=ssh.service
[Service]
Type=oneshot
ExecStart=/bin/true
[Install]
WantedBy=multi-user.target
Code: Select all
# cat /etc/systemd/system/virtualbox-leon-04.service | grep -v "^#"
[Unit]
Description=VirtualBox %N machine ...
Requires=ssh.service
After=ssh.service
PartOf=virtualbox-leon-all.service
[Service]
Type=simple
ExecStart=/bin/bash -c "/usr/bin/VBoxHeadless -s Leon-$(echo %N | cut -d '-' -f3)"
Restart=always
ExecStop=/bin/bash -c "/usr/local/bin/virtualbox_stop_vm.sh Leon-$(echo %N | cut -d '-' -f3)"
TimeoutStopSec=200s
KillMode=none
[Install]
WantedBy=multi-user.target
WantedBy=virtualbox-leon-all.service
Now, copy the guest files as many times as you want, to get this:
Code: Select all
# for i in 07 08 09 10 11 12 ; do cp -a /etc/systemd/system/virtualbox-leon-04.service /etc/systemd/system/virtualbox-leon-${i}.service ; done
# ll /etc/systemd/system/
total 92
drwxr-xr-x 2 root root 4096 Jun 25 2016 getty@.service.d
drwxr-xr-x 2 root root 4096 Jun 25 2016 getty.target.wants
drwxr-xr-x 2 root root 4096 Mar 27 03:27 multi-user.target.wants
drwxr-xr-x 2 root root 4096 Jun 25 2016 network-online.target.wants
drwxr-xr-x 2 root root 4096 Jun 25 2016 paths.target.wants
drwxr-xr-x 2 root root 4096 Jul 10 2016 remote-fs.target.wants
lrwxrwxrwx 1 root root 9 Dec 1 09:54 samba-ad-dc.service -> /dev/null
drwxr-xr-x 2 root root 4096 Jun 25 2016 sockets.target.wants
-rw-r--r-- 1 root root 507 Jul 10 2016 ssh.service
drwxr-xr-x 2 root root 4096 Jun 25 2016 sysinit.target.wants
lrwxrwxrwx 1 root root 35 Jun 25 2016 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x 2 root root 4096 Jun 25 2016 timers.target.wants
lrwxrwxrwx 1 root root 9 Dec 27 19:37 vboxweb.service -> /dev/null
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-02.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-03.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-04.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-05.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-06.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-07.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-08.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-09.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-10.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-11.service
-rw-r--r-- 1 root root 879 Mar 27 03:16 virtualbox-leon-12.service
-rw-r--r-- 1 root root 1368 Mar 27 03:06 virtualbox-leon-all.service
drwxr-xr-x 2 root root 4096 Mar 27 03:27 virtualbox-leon-all.service.wants
Code: Select all
# systemctl enable virtualbox-leon-all.service
# systemctl enable virtualbox-leon-02.service
# systemctl enable virtualbox-leon-03.service
# systemctl enable virtualbox-leon-04.service
# systemctl enable virtualbox-leon-05.service
# ll /etc/systemd/system/virtualbox-leon-all.service.wants/
total 0
lrwxrwxrwx 1 root root 46 Mar 27 03:27 virtualbox-leon-02.service -> /etc/systemd/system/virtualbox-leon-02.service
lrwxrwxrwx 1 root root 46 Mar 27 03:27 virtualbox-leon-03.service -> /etc/systemd/system/virtualbox-leon-03.service
lrwxrwxrwx 1 root root 46 Mar 27 03:27 virtualbox-leon-04.service -> /etc/systemd/system/virtualbox-leon-04.service
lrwxrwxrwx 1 root root 46 Mar 27 03:27 virtualbox-leon-05.service -> /etc/systemd/system/virtualbox-leon-05.service
Code: Select all
# systemctl start virtualbox-leon-all.service
Code: Select all
# psa virtua
* I remind you that With NPTL ps and top no longer show threads. You can use any of: '-m m -L -T H' in ps or the H key in top to show them.
* also try: ps axjf
c="ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,size,tty,nice,nlwp,psr,sgi_p,bsdstart,bsdtime,args k start_time"
m
root 5999 1 0.1 0.1 244600 8872 19188 ? 0 1 1 * 00:30 0:29 /usr/lib/virtualbox/VBoxXPCOMIPCD
root 6005 1 0.3 0.2 1006180 16868 34844 ? 0 17 1 * 00:30 1:01 /usr/lib/virtualbox/VBoxSVC --auto-shutdown
root 7016 7014 0.5 0.6 1334064 52632 134884 ? 0 14 0 * 00:33 1:22 /usr/lib/virtualbox/VirtualBox
root 30455 1 7.9 3.4 2059288 270148 116088 ? 0 30 1 * 03:28 7:05 /usr/lib/virtualbox/VBoxHeadless -s Leon-05
root 398 1 8.1 3.0 1999412 242812 115924 ? 0 30 0 * 03:32 6:58 /usr/lib/virtualbox/VBoxHeadless -s Leon-04
root 494 1 179 23.5 6307104 1858272 152796 ? 0 34 1 * 03:32 153:09 /usr/lib/virtualbox/VBoxHeadless -s Leon-03
root 515 1 33.8 1.3 1949168 104148 109912 ttyS0 0 31 0 * 03:32 28:51 /usr/lib/virtualbox/VBoxHeadless -s Leon-02
Also, the guest units can probably hard links; I did not try; would be easier to update them.
Finaly, I have to also publish my stop script:
Code: Select all
# cat /usr/local/bin/virtualbox_stop_vm.sh
#!/bin/bash
[ "$1" = "" ] && {
echo "$0: needs an argument: VM to be turned off".
exit 1
}
logfile="/dev/shm/$(basename "$0").$1.$(/bin/date +%Y-%m-%d_%H-%M-%S)"
echo "*Begin."
n=25
while [ $n -gt 0 ]
do
/usr/bin/VBoxManage controlvm "$1" acpipowerbutton &
/bin/sleep 3
n=$(($n-1))
pid=$!
/bin/sleep 3
[ -d /proc/${pid} ] && n=0
echo ".s"
/usr/bin/VBoxManage showvminfo "$1" | /bin/grep "^State:" >"${logfile}" &
/usr/local/bin/wait_pid_or_kill.sh $! 2
cat "${logfile}" | /bin/grep -e "stopping" -e "powered off" -e "aborted" >/dev/null && n=-1
echo "*n: $n"
done
echo "***n: $n"
[ $n -le 0 ] && /usr/bin/VBoxManage controlvm "$1" poweroff &
pid="$(ps aux | grep -i virtua | grep -v "$0" | grep "$1" | awk '{print $2}')"
echo "*PID: $pid"
[ "$pid" != "" ] && {
sleep 10
pid="$(ps aux | grep -i virtua | grep -v "$0" | grep "$1" | awk '{print $2}')"
echo "*PID: $pid"
[ "$pid" != "" ] && {
echo "Need to kill $pid :"
ps aux | grep -i virtua | grep "$1" | grep -v "$0"
kill $pid
}
sleep 10
}
echo "*END."
- process taking long time to terminate in the guest
- if we ask for a stop, just after a start, and, during guest initialisation, a small fsck is run
I could not make these latencies too long, because, we still need to terminate the guests before the UPS goes out of battery.
It's far from perfect, but considering how old the tutos are in Google, this may help some people in the future.
If yout unit file can have exactly the same name as the VirtualBox guest name, the exec lines can become more simple:
Code: Select all
ExecStart=/bin/bash -c "/usr/bin/VBoxHeadless -s "%N"
ExecStop=/bin/bash -c "/usr/local/bin/virtualbox_stop_vm.sh "%N"
Code: Select all
# cat wait_pid_or_kill.sh
#!/bin/bash
[ "$1" = "" ] && {
echo "$0 requires first argument a PID."
exit 1
}
[ "$2" = "" ] && {
echo "$0 requires second argument a timeout in s."
exit 1
}
[ "$1" = "-h" -o "$2" = "-h" ] && {
echo "$0 Wait for a PID to terminate, or kill it after timeout."
exit 0
}
pid=$1
time=$2
[ $pid -gt 0 ] || {
echo "$0 First argument does not seem a number"
exit 1
}
[ $time -gt 0 ] || {
echo "$0 Second argument does not seem a number"
exit 1
}
i=$time
while [ $i -gt 0 ]
do
sleep 1
i=$(($i-1))
[[ -d /proc/$pid ]] || break
done
[ $i -gt 0 ] && exit 0
basename "$0" | grep "die" >/dev/null && exit 1
basename "$0" | grep "kill" >/dev/null && [ -d /proc/$pid ] && kill $pid