无法在 VirtualBox 运行时休眠

无法在 VirtualBox 运行时休眠

当虚拟机正在运行(XP Guest)时,我无法休眠和挂起我的戴尔笔记本电脑。我尝试了默认内核方法、uswsusp 和 tuxonice,但都不起作用。但如果我关闭虚拟机,则休眠和挂起可以正常工作。以下是系统规格。操作系统:Ubuntu 10.10 64 位(已完全更新)内存:4GB 交换:8 GB 根:500 GB(其中约 79% 是空闲的)

我的笔记本电脑型号是 Dell Inspiron N5010。它有 ATI HD 5000 系列图形芯片组,我使用专有驱动程序,通过 jockey 安装。

谢谢。

答案1

我遇到了同样的问题,“暂停”虚拟客户机 XP(HostKey-P)有时有效,但通常无效。将 VM-Guest-XP 置于“已保存状态”可让系统再次休眠,没有任何问题。
我编写了一个小脚本,将其放入/etc/pm/sleep.d/05_virtualbox(别忘了chmod a+x 05_virtualbox),电源管理将执行保存机器状态并自动在虚拟机上启动程序...

#!/bin/sh

# File: /etc/pm/sleep.d/05_virtualbox  #(at least in ubuntu/fedora)
# 
# This hack saves-state all VirtualBox-VM's off user $VBUSER on hibernate/suspend,
#   saves the list of this VMs in $VM_LIST_FILE, and on thaw/resume it starts all
#   VMs in that list again, and removes $VM_LIST_FILE.
# BUGS: don't use the same NAME for different VMs, or rewrite the script to use UUIDs
#
# a REAL hack, tried to comment as much as possible, but the chosen syntax is obfuscated, 
#   sorry...also sorry for the bad english...
#
# Writer (guilty person): Lutz Langenbach
# Copyleft: do what you want with the Code
# Help: VBoxManage 2>&1 |less or http://www.virtualbox.org/manual/ch08.html

VM_LIST_FILE=/var/tmp/vms-in-saved-state-list
VBUSER=Put_YOUR_username_here

PATH=/sbin:/usr/sbin:/bin:/usr/bin

case "${1}" in
  suspend|hibernate)
    # print list of running VM's output: "vm-name" {vm-uuid}\n
    # extract only the name of VM's and send 
    echo -n "Send savestate to VM's:"
    sudo  -u $VBUSER  VBoxManage list runningvms \
    |perl -ne 'chomp;s/^"([^"]*)".*/\1/; print $_; system("sudo -u '"$VBUSER"' VBoxManage controlvm \"$_\" savestate && echo \"$_\">>'"$VM_LIST_FILE"'");'
    echo ..done
    ;;
  resume|thaw)
    # get each line in $VM_LIST_FILE, use it as VM-Name and send start to it 
    echo -n "Send resume to VM's"
    cat $VM_LIST_FILE | perl -ne 'chomp;s/^"([^"]*)".*/\1/; system("sudo -u '"$VBUSER"' VBoxManage startvm \"$_\"");'
    rm -f $VM_LIST_FILE
    echo .
    ;;
  *)
    echo "Don't know what to do, 1st Arg was:${1}; Must be suspend|hibernate|resume|thaw"
    ;;
esac

答案2

根据对原始问题的评论:

我发现 VirtualBox 中有一个功能可以保存虚拟机的当前状态。它与休眠非常相似,只是我没有明确休眠客户操作系统。此外,这个过程非常快,之后我可以正常休眠主机操作系统。

此功能称为Save Machine State

答案3

@ Lutz L. 首先感谢您提供的脚本。我在装有 VB 4.3.10 的 Xubuntu 14.04 和运行在休眠模式下的 Xubuntu 12.04 或 Windwos XP Guest 上也遇到了同样的问题。

第一次尝试时,该脚本似乎运行完美。但下次主系统从休眠状态恢复时,虚拟机不会自动恢复。

这是我在“pm-suspend.log”文件中找到的消息:

运行挂钩 /etc/pm/sleep.d/05_virtualbox thaw hibernate:将简历发送到 VM'sVBoxManage:错误:虚拟机“Xubuntu12”在启动过程中意外终止,退出代码为 1 VBoxManage:错误:详细信息:代码 NS_ERROR_FAILURE(0x80004005),组件 Machine,接口 IMachine 等待 VM“Xubuntu12”启动...

我可以手动恢复访客,这没有问题,但不太舒服。

PS:这个问题早已为人所知,正如您在此处所见:https://www.virtualbox.org/ticket/7716

编辑:有一个类似的脚本:

#!/bin/bash
# Script to pause/resume running VBox VMs on hibernate/thaw
operation="$1"

# This script is invoked as root, but root cannot use VBoxManage to
# control the VMs of other users. So we obtain the members of the
# 'vboxusers' group and re-execute as each user in turn
if [ $(id -u) -eq 0 ] ; then
    # running as root...
    vboxusers=$(grep ^vboxusers /etc/group | cut -d ':' -f 4- | tr ',' ' ')
    for user in $vboxusers; do
        echo "restarting as $user..."
        su - $user -c "$0 $operation" || exit $?
    done
    exit 0
fi

hibernated_vm_list=$HOME/.vbox-hibernated-vms

# get a list of all running VMs, save their state to disk and
# remember that we have done this
hibernate_vms()
{
    rm -f $hibernated_vm_list

    # each line in list is: "vmname" {vm-uuid}
    local vm_list="$(VBoxManage list runningvms)"
    if [ -z "$vm_list" ] ; then # nothing to do
        return 0
    fi

    local tempfile="/tmp/VBoxPauseResume.tmp"
    echo "$vm_list" > $tempfile
    local pids=""
    while read line ;
    do
        vm_name=$(echo "$line" | sed 's/\(".*"\).*/\1/')
        vm_uuid=$(echo "$line" | sed 's/.*\({.*}\)/\1/')
        echo "saving state of vm $vm_name for user $user"
        (VBoxManage controlvm $vm_uuid savestate && \
            echo "$vm_name $vm_uuid" >> $hibernated_vm_list && \
            echo "saved state of vm $vm_name for user $user") &
        pids="$pids $!"
    done < $tempfile
    wait $pids
    rm -f $tempfile
}

# resumes any VMs that were saved by hibernate_vms(). Uses parallel
# child processes to thaw several VMs faster
thaw_vms()
{
    if [ -e $hibernated_vm_list ] ; then
        local pids=""
        while read line ;
        do
            vm_name=$(echo "$line" | sed 's/\(".*"\).*/\1/')
            vm_uuid=$(echo "$line" | sed 's/.*\({.*}\)/\1/')
            echo "resuming vm $vm_name for user $user"
            VBoxManage startvm $vm_uuid &
            pids="$pids $!"
        done < $hibernated_vm_list
        wait $pids
        rm -f $hibernated_vm_list
    fi
}

case $operation in
    hibernate) hibernate_vms ;;
    suspend) ;;
    thaw) thaw_vms ;;
    resume) ;;
esac

(将此脚本保存为 /etc/pm/sleep.d/02-VirtualBox,并确保其可执行)

来源:http://angryfifer.blogspot.de/2012/02/linux-hibernation-and-virtualbox.html

遗憾的是,这个脚本也存在同样的问题......

答案4

@TuKsn

解决这个问题非常简单——必须设置变量 DISPLAY。

VirtualBox 在以 gui 模式启动虚拟机时会使用它。当我通过 ssh 登录并希望以 gui 模式启动虚拟机时,也会出现同样的问题。

感谢您的脚本,它运行得很好!

然而,我必须添加一些修改以便存储虚拟机的工作模式(即“gui”或“headless”或“sdl”),以便正确重启虚拟机。

下面是包含我的更正内容的脚本:


#!/bin/bash
# Script to pause/resume running VBox VMs on hibernate/thaw

# Set your display here
display=":0.0"

operation="$1"

# This script is invoked as root, but root cannot use VBoxManage to
# control the VMs of other users. So we obtain the members of the
# 'vboxusers' group and re-execute as each user in turn
if [ $(id -u) -eq 0 ] ; then
    # running as root...
    vboxusers=$(grep ^vboxusers /etc/group | cut -d ':' -f 4- | tr ',' ' ')
    for user in $vboxusers; do
        echo "restarting as $user..."
        su - $user -c "$0 $operation" || exit $?
    done
    exit 0
fi

hibernated_vm_list=$HOME/.vbox-hibernated-vms

# get a list of all running VMs, save their state to disk and
# remember that we have done this
hibernate_vms()
{
    rm -f $hibernated_vm_list

    # each line in list is: "vmname" {vm-uuid}
    local vm_list="$(VBoxManage list runningvms)"
    if [ -z "$vm_list" ] ; then # nothing to do
        return 0
    fi

    local tempfile="/tmp/VBoxPauseResume.tmp"
    echo "$vm_list" > $tempfile
    local pids=""
    while read line ;
    do
        vm_name=$(echo "$line" | sed 's/\(".*"\).*/\1/')
        vm_uuid=$(echo "$line" | sed 's/.*\({.*}\)/\1/')
        vm_type=$(VBoxManage showvminfo $vm_uuid | grep "Session type:" | awk '{print $NF}')
        case $vm_type in
            "headless") ;;
            "sdl") ;;
            "GUI/Qt") vm_type="gui" ;;
            *) vm_type="gui" ;;
        esac
        echo "saving state of vm $vm_name for user $user from mode $vm_type"
        (VBoxManage controlvm $vm_uuid savestate && \
            echo "$vm_name $vm_uuid $vm_type" >> $hibernated_vm_list && \
            echo "saved state of vm $vm_name for user $user") &
        pids="$pids $!"
    done < $tempfile
    wait $pids
    rm -f $tempfile
}

# resumes any VMs that were saved by hibernate_vms(). Uses parallel
# child processes to thaw several VMs faster
thaw_vms()
{
    if [ -e $hibernated_vm_list ] ; then
        local pids=""
        while read line ;
        do
            vm_name=$(echo "$line" | sed 's/\(".*"\).*/\1/')
            vm_uuid=$(echo "$line" | sed 's/.*\({.*}\)/\1/' | awk '{print $1}')
            vm_type=$(echo "$line" | sed 's/.*\({.*}\)/\1/' | awk '{print $2}')
            echo "resuming vm $vm_name for user $user in mode $vm_type"
            DISPLAY=$display VBoxManage startvm $vm_uuid --type $vm_type &
            pids="$pids $!"
        done < $hibernated_vm_list
        wait $pids
        rm -f $hibernated_vm_list
    fi
}

case $operation in
    hibernate) hibernate_vms ;;
    suspend) ;;
    thaw) thaw_vms ;;
    resume) ;;
esac

相关内容