回答:
Virtual Boxの仮想マシンの実行中に本当にシャットダウンする必要がある場合は、シャットダウンプロセスが開始する前にマシンの状態を保存するコマンドを配置する手動シャットダウン用の独自のスクリプトを定義できます。
VBoxManage controlvm <name> savestate # <name> is the name of your VM
gnome-session-quit --power-off # this example displays the power-off dialog for >11.10
または、シャットダウン時に常に実行されるスクリプトを生成することもできます。
sudo reboot
プログラムを使用する場合、アプリケーションにそのような状況に対処する時間を与えずに、プログラムを自動的に終了させるkillシグナルが与えられます。これはバグではありません。常に同じように動作し、それは予想される動作です。
あなたが与えられたコマンドを参照することができます同様の質問があり、あなたは押すとshutdown
、reboot
、suspend
、ユーザメニュー上などのボタンは、そのような解決策は、実行中のアプリケーションとその好適でウィンドウを閉じようとするときに(何をすべきかを尋ねるべきあなたの場合)sudo shutdown
アプローチへ。見てください
起動ジョブ、開始および停止スクリプトを含む、より洗練されたアプローチをお勧めします。例として、私はWindows XPを使用しています。ホームディレクトリでtombert ...を使用できるため、それに応じて変更する必要があります。これには、仮想マシンを適切に処理する(再起動、シャットダウン、電源ボタンを押す)何でもできるという利点があります。
最初にupstartジョブを/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
upstartジョブは、ランレベル2(グラフィカルモード)で仮想マシンを起動しnice
ます。私の場合、優先順位はで増加します。仮想マシンを適切にシャットダウンするには、kill signal SIGCONT
ステートメントを使用して、起動の終了を「無効」にする必要があります。これにより、最初は仮想マシンが実行されたままになります(デフォルトは回避されますSIGTERM
)。120秒後、SIGKILL
とにかく送信されます。代わりに、winxpvm-stop.sh
スクリプトを実行しています。
補足1:スタンザstart on started runlevel [2]
とstop on starting runlevel [!2]
は機能しません。具体的にはその仕事に言及する必要がありrc
ます。
注2:アップスタートマニュアルからもわかりにくい点:kill signal
スタンザは5秒後に送信される信号を指定します。この例では、SIGTERM
(デフォルト)からSIGCONT に設定していますが、5秒のタイムアウトを変更できませんでした。kill timeout
スタンザは、その後のタイムアウトを指定するSIGKILL
1を変更することはできません合図-送信されます。したがって、改善は新しいスタンザterm signal
とを定義することterm timeout
です。
ここで、起動スクリプト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
すべての設定などはユーザーモードで行われるため(私のログインはtombertであるため)、rootとして実行されている場合でも、アカウントをtombertに変更します。もちろん、ユーザーはupstart構成で変更できますが、このソリューションでは、コンソールから「手動」で仮想マシンを起動/停止するオプションが残ります。
より興味深いのは、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
最初に、起動スクリプトと同じようにします。ユーザーをrootからアカウントtombertに変更します。次に、関数を見てみましょうdostop
。まず、仮想マシンが実行されているかどうかを確認しています。次に、を使用してシャットダウンをWinXPに直接送信することにより、「ソフトに」シャットダウンしようとしていguestcontrol
ます。ここでは、WinXPアカウントの資格情報(私の場合はtombertとパスワード)を指定する必要があります。Windows shutdown
はすべてのアプリケーションを正常に閉じ、オペレーティングシステムの電源をオフにします(通常)。次に、を使用して仮想マシンの状態を継続的に確認しますshowvminfo
。1秒のタイムアウトでこれを少なくとも60回実行すると(適切と思われる操作をすべて実行します)、仮想マシンを正常にシャットダウンするのに十分な時間が残ります。への呼び出しに注意してくださいshowvminfo
(少なくとも私のコンピューターでは)1秒も少しかかるので、私の場合はこれで120秒程度になります。すべてがブレーキをかけたら、poweroff
ステートメントを使用して強制的にシャットダウンできます。
も表示されますがacpipowerbutton
、未使用です。これは、信頼できる動作をしないためです。Windowsまたはさらに悪いことに複数のユーザーにログオンしている場合、Windowsは確認のシャットダウンダイアログを表示して、システムのシャットダウンを防止します。これも理由であるacpibutton
における/etc/default/virtualbox
信頼性が100%動作しません。また、poweroff
は仮想マシンを強制的にシャットダウンします-電源ボタンを長押しするのと同じです。したがって、これを空に設定することをお勧めします。
/ 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=""
完璧にするには、電源ボタンの動作を変更する必要があります。
/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
...
...
欠点が1つ残っています。仮想マシンがまだ起動していて、ゲストコントロールサービスが(仮想マシンで)起動していない場合、シャットダウンコマンドは受信されません。まれなケース...それについて考えてください。
それでお役に立てば幸いです。
VERR_INVALID_PARAMETER
ます。
以下を使用して、シャットダウン要求を仮想マシンに送信できます。
VBoxManage controlvm <vm_name> acpipowerbutton
ただし、これをinitスクリプトで行う場合、シャットダウンが完了するまでスクリプトは終了しません。ループ内lsof
またはfuser
ループ内でVMのドライブファイル(.vdi)をポーリングすることで、それを検出できる場合があります。または安価な回避策として、sleep 20
十分かもしれません。
以下は、私のinitスクリプトのcloseブロックで現在使用しているものです。
# This always returns 0, even if an error is displayed!
su - "$DAEMONUSER" VBoxManage controlvm "$VMNAME" acpipowerbutton
# Wait until the disk file is no longer open...
for attempt in `seq 1 20`
do
fuser "$VMDISKIMAGE" >/dev/null 2>&1 || break
sleep 2
done
return 0 # A better script would return success/fail
私が定義したファイルの上部付近:
VMDISKIMAGE="/home/$DAEMONUSER/VirtualBox VMs/$VMNAME/$VMNAME.vdi"
これは実際にはVirtualBoxアプリ自体を閉じない場合がありますが、VMのシャットダウンが完了するまで待機します。また、仮想マシンが起動中の場合(多くのオペレーティングシステムはこの段階で電源オフボタンを無視する)、またはACPIサポートのない古いシステムをエミュレートしている場合も機能しません。
reboot
12.10 のマニュアルページには、「-forceで呼び出された場合、またはランレベル0または6で呼び出された場合、このツールは、reboot(2)システムコール自体を呼び出し、システムを直接再起動します。それ以外の場合は、shutdown(8)ツールを呼び出します。適切な引数。 "; のマニュアルページにshutdown
は、「TIMEが経過すると、shutdownはシステムを適切なランレベルにするためのリクエストをinit(8)デーモンに送信します。」