Eu recomendaria uma abordagem mais sofisticada, incluindo um trabalho inicial, um script de início e parada. Como exemplo, estou usando o Windows XP, pois meu diretório pessoal permite usar tombert ..., que você deve alterar de acordo. Ele tem a vantagem de tudo o que você faz (reinicialização, desligamento, pressionamento do botão liga / desliga) e lida com sua máquina virtual .
Primeiro, o trabalho inicial, coloque em /etc/init/winxpvm.conf:
description "WinXP VirtualBox job"
author "Thomas Perschak"
## 0: system halt
## 1: single-user mode
## 2: graphical multi-user plus networking
## 6: system reboot
start on started rc RUNLEVEL=[2]
stop on starting rc RUNLEVEL=[!2]
## upstart config
kill timeout 120
kill signal SIGCONT
nice -10
## start WinXP VirtualBox
exec /home/tombert/scripts/winxpvm-start.sh
## stop WinXP VirtualBox
pre-stop exec /home/tombert/scripts/winxpvm-stop.sh
O trabalho inicial inicia a máquina virtual no nível de execução 2 (que está no modo gráfico) e, no meu caso, aumenta a prioridade com nice
. Para desligar bem a máquina virtual, preciso "desativar" a terminação inicial usando a kill signal SIGCONT
instrução Isso deixa a máquina virtual em execução no início (evitando o padrão SIGTERM
). Após 120 segundos, o SIGKILL
envio é assim mesmo. Em vez disso, estou executando o winxpvm-stop.sh
script.
Nota lateral 1: As estrofes start on started runlevel [2]
e stop on starting runlevel [!2]
não funcionam. É preciso mencionar especificamente o trabalho rc
.
Nota lateral 2: O que é confuso também no manual inicial: A kill signal
estrofe especifica o sinal enviado após 5 segundos. Neste exemplo, defini-o de SIGTERM
(padrão) para SIGCONT - mas o tempo limite de 5 segundos não foi possível alterar. A kill timeout
estrofe especifica o tempo limite após o qual o SIGKILL
envio é enviado - qual sinal não pode ser alterado. Uma melhoria, portanto, seria definir novas estrofes term signal
e term timeout
.
Aqui o script de início winxpvm-start.sh:
#! /bin/bash -e
function dostart()
{
echo -n "Running WinXP ... "
vboxheadless --startvm WinXP
echo "now closed"
}
export -f dostart
if [ $(whoami) != "tombert" ]; then
su -c dostart tombert
else
dostart
fi
Como todas as configurações etc. são feitas no modo de usuário (como meu login é tombert ), mesmo quando executado como root, mudo a conta para tombert . Obviamente, o usuário pode ser alterado na configuração inicial, mas essa solução me deixa a opção de iniciar / parar a máquina virtual "manualmente" no console.
O mais interessante é o script de desligamento no winxpvm-stop.sh:
#! /bin/bash
function dostop()
{
## check if WinXP is running
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "WinXP not running"
exit
fi
## try gracefully shutdown
echo -n "Shutting down WinXP ... "
#vboxmanage controlvm WinXP acpipowerbutton
vboxmanage guestcontrol WinXP execute --image "%SystemRoot%\system32\shutdown.exe" --username tombert --password <mypassword> --wait-exit -- "-s" "-f" "-t" "0" &> /dev/null
## check vm status
INDEX=60
while [ $INDEX -gt 0 ]; do
echo -n "$INDEX "
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "gracefully done"
break
fi
sleep 1
let INDEX+=-1
done
## close forcefully
if [ $INDEX -eq 0 ]; then
vboxmanage controlvm WinXP poweroff &> /dev/null
echo "forcefully done"
fi
}
export -f dostop
if [ $(whoami) != "tombert" ]; then
su -c dostop tombert
else
dostop
fi
Primeiro, faço o mesmo que no script inicial - estou mudando o usuário da raiz para a minha conta tombert . Agora vamos olhar para a função dostop
. Primeiro, estou verificando se a máquina virtual está em execução. Então, eu estou tentando "suavemente" o desligamento enviando um desligamento diretamente para o WinXP usando guestcontrol
. Aqui você deve fornecer as credenciais da conta WinXP, que no meu caso é tombert e uma senha. O Windows shutdown
irá fechar todos os aplicativos normalmente e desligar o sistema operacional (normalmente). Em seguida, vamos verificar o estado da máquina virtual continuamente usando showvminfo
. Fazer isso pelo menos 60 vezes com 1 segundo de tempo limite (faça o que você achar apropriado aqui) deve deixar a máquina virtual tempo suficiente para desligar normalmente. Observe que a chamada parashowvminfo
também demora um pouco menos de um segundo (pelo menos no meu computador), o que gera aproximadamente 120 segundos no meu caso. Se tudo frear, podemos desligar à força usando a poweroff
declaração.
Você também deve ver o acpipowerbutton
, mas não utilizado. Isso ocorre porque não funciona de maneira confiável. Se você estiver conectado ao Windows, ou ainda pior, vários usuários, o Windows mostrará uma caixa de diálogo de encerramento de confirmação, impedindo o desligamento do sistema. Esta também é a razão pela qual o acpibutton
in /etc/default/virtualbox
não funcionará 100% confiável. Além disso, o poweroff
desligamento forçado da máquina virtual é o mesmo que pressionar um botão liga / desliga por muito tempo. Portanto, é melhor definir isso como vazio:
Trecho de / etc / default / virtualbox:
# SHUTDOWN_USERS="foo bar"
# check for running VMs of user 'foo' and user 'bar'
# 'all' checks for all active users
# SHUTDOWN=poweroff
# SHUTDOWN=acpibutton
# SHUTDOWN=savestate
# select one of these shutdown methods for running VMs
# acpibutton and savestate causes the init script to wait
# 30 seconds for the VMs to shutdown
SHUTDOWN_USERS=""
SHUTDOWN=""
Para torná-lo perfeito, convém alterar o comportamento do botão liga / desliga:
Trecho de /etc/acpi/powerbtn.sh:
#!/bin/sh
# /etc/acpi/powerbtn.sh
# Initiates a shutdown when the power putton has been
# pressed.
# @backup
# plain shutdown
/sbin/shutdown -h now "Power button pressed"
# fini
exit 0
...
...
Ainda existe uma pequena desvantagem. Quando a máquina virtual ainda estiver inicializando e o serviço de controle de convidados não estiver ativo (na máquina virtual), ele não receberá o comando shutdown. Um caso raro ... mas pense nisso.
É isso, espero que ajude.
reboot
12.10 diz "Quando chamada com --force ou quando no nível de execução 0 ou 6, esta ferramenta chama a própria chamada de sistema reboot (2) e reinicia diretamente o sistema. Caso contrário, isso simplesmente chama a ferramenta shutdown (8) com os argumentos apropriados. "; e a página do manualshutdown
diz "Depois que o TIME terminar, o shutdown envia uma solicitação ao daemon init (8) para trazer o sistema para o nível de execução apropriado".