主机重新启动时安全关闭VirtualBox计算机


8

我在Ubuntu 11.10上的Virtualbox中运行Windows 7。一切正常。我在启动时正在运行它,但是重新启动时遇到了问题。

当我键入sudo reboot now时,虚拟Windows 7的状态不会保存。重新启动后,virtualbox启动,但不是运行的Windows,而是Windows 7的崩溃启动菜单,并且Windows重新启动。

Ubuntu可以选择在主机重启之前向虚拟机发送一些信号来安全关闭实例的选项吗?

Answers:


6

如果您确实需要在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

或者,您也可以生成始终在关机时运行的脚本。


4

如果使用sudo reboot程序,则将发出终止信号,自动终止程序,而不会给应用程序时间来处理这种情况。这不是错误,它始终以相同的方式工作,这是预期的行为。

还有一个类似的问题在这里你可以看到哪些命令给出当你按下shutdownrebootsuspend,用户菜单等按键,这样的解决方案应该问你们是不是要关闭一个窗口与正在运行的应用程序,它最好的时候做什么(在您的情况)sudo shutdown。看一看


重新启动最近变得更加礼貌了吗?reboot在12.10中的手册页上说:“当使用--force调用时,或者在运行级别0或6中调用时,此工具将调用本身的reboot(2)系统调用并直接重新引导系统。否则,仅使用以下命令调用shutdown(8)工具:适当的论点。”;手册页上shutdown说:“一旦经过了TIME,关机就会向init(8)守护程序发送一个请求,以将系统置于适当的运行级别。”
echristopherson

4

我建议使用更复杂的方法,包括新手作业,启动和停止脚本。例如,我使用的是Windows XP,因为我的主目录允许使用tombert ...,您应该进行相应的更改。它的优点是无论您做什么(重新启动,关闭,按下电源按钮),都能很好地处理您的虚拟机

首先,将新贵作业放入/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发送之前的超时-该信号不能更改。因此,一种改进是定义新的节term signalterm 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还需要不到一秒钟的时间(至少在我的计算机上),因此在我的情况下大约需要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
...
...

还剩下一个小缺点。当虚拟机仍在引导且guest虚拟机控制服务未启动(在虚拟机中)时,它将不会收到shutdown命令。罕见的情况...但是请考虑一下。

就是这样,希望对您有所帮助。


就像超级按钮(Windows XP guest虚拟机)一样工作,除了VERR_INVALID_PARAMETER如果我以脚本中给定的用户身份通过​​RDC登录后,它似乎在主机端抛出了一个问题,随后guest虚拟机继续运行。
echristopherson

我尝试同时使用本机RDC和VirtualBox顶部的RDC。没有这样的错误。可能与virtualbox.org/ticket/8197有关
tombert

2

按照答案更改系统策略以进行重新引导

您无法将其简化为reboot。AFAIK init.d脚本将不起作用,因为它花费了太多时间,但是您可以运行以下命令:

VBoxManage controlvm <vm> savestate&&reboot

<vm>虚拟机的名称在哪里


1

您可以使用以下方式向虚拟机发送关闭请求:

VBoxManage controlvm <vm_name> acpipowerbutton

但是,如果您在初始化脚本中执行此操作,则在关闭完成之前,脚本不应退出。我们可以通过lsoffuser循环轮询VM的驱动器文件(.vdi)来检测到该错误。或者作为便宜的解决方法,sleep 20可能就足够了。

这是我当前在初始化脚本的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的旧系统,则它也不起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.