호스트 재부팅시 virtualbox 시스템을 안전하게 닫습니다.


8

Ubuntu 11.10의 Virtualbox에서 Windows 7을 실행하고 있습니다. 모든 것이 잘 작동합니다. 시작할 때 실행하고 있지만 재부팅하는 데 문제가 있습니다.

내가 입력 sudo reboot now하면 가상 Windows 7의 상태가 저장되지 않습니다. 재부팅 후 virtualbox가 시작되지만 실행중인 Windows 대신 Windows 7 충돌 부팅 메뉴가 표시되고 창이 다시 부팅됩니다.

Ubuntu가 호스트를 재부팅하기 전에 인스턴스를 안전하게 닫기 위해 가상 상자에 신호를 보낼 수있는 옵션이 있습니까?

답변:


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프로그램 을 사용 하는 경우 응용 프로그램에 그러한 상황에 대처할 시간을주지 않고 종료 신호가 자동으로 종료됩니다. 이것은 버그가 아니며 항상 같은 방식으로 작동했으며 예상되는 동작입니다.

당신이 제공하는 명령을 볼 수있는 비슷한 질문이 있습니다 당신은 눌렀을 때 shutdown, reboot, suspend, 사용자 메뉴 등 버튼, 이러한 솔루션은 실행중인 응용 프로그램과 해당 바람직와 창을 닫으려고 할 때에 (질문에 답해야한다 당신의 경우) sudo shutdown접근. 보세요


최근에 재부팅이 더 정중 해졌습니까? reboot12.10 의 매뉴얼 페이지에 "--force로 호출되거나 런레벨 0 또는 6에있을 때이 도구는 reboot (2) 시스템 호출 자체를 호출하고 시스템을 직접 재부팅합니다. 그렇지 않으면 간단히 shutdown (8) 도구를 호출합니다. 적절한 주장. "; 그리고 맨 페이지는 shutdown"시간이 경과되면, 종료가 적절한 실행 레벨에 이르기까지 시스템을 가지고 (8) 데몬은 init에 요청을 보냅니다."라고
echristopherson

4

upstart 작업, 시작 및 중지 스크립트를 포함하여보다 정교한 접근 방식을 권장합니다. 예를 들어 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 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로 변경합니다 . 물론 사용자는 시작 구성에서 변경 될 수 있지만이 솔루션을 사용하면 콘솔에서 "수동으로"가상 머신을 시작 / 중지 할 수 있습니다.

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/virtualbox100 % 신뢰할 수있는 작동하지 않습니다. 또한 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
...
...

하나의 작은 단점이 남아 있습니다. 가상 머신이 여전히 부팅 중이고 게스트 제어 서비스가 작동하지 않으면 (가상 머신에서) shutdown 명령을받지 않습니다. 드문 경우이지만 ... 생각하십시오.

그게 도움이되기를 바랍니다.


스크립트에 제공된 사용자로 RDC를 통해 로그인 한 후 게스트가 계속 실행되는 경우 호스트 측에서 버리는 것만 제외하고 는 참 (Windows XP 게스트) VERR_INVALID_PARAMETER처럼 작동합니다.
echristopherson

기본 RDC와 VirtualBox 상단의 RDC를 모두 사용해 보았습니다. 그런 오류가 없습니다. 아마 virtualbox.org/ticket/8197와 관련이 있습니다
tombert

2

재부팅에 대한 시스템 정책을 변경하려면 답변을 따르십시오

이 작업을 간소화 할 수 없습니다 reboot. init.d시간이 너무 많이 걸리기 때문에 AFAIK 스크립트가 작동하지 않지만 다음과 같이 명령을 실행할 수 있습니다.

VBoxManage controlvm <vm> savestate&&reboot

<vm>가상 머신의 이름은 어디에 있습니까?


1

다음을 사용하여 가상 머신에 종료 요청을 보낼 수 있습니다.

VBoxManage controlvm <vm_name> acpipowerbutton

그러나 init 스크립트에서이 작업을 수행하면 종료가 완료 될 때까지 스크립트가 종료되지 않아야합니다. VM의 드라이브 파일 (.vdi)을 루프 로 lsof또는 fuser루프 로 폴링하여이를 감지 할 수 있습니다 . 또는 저렴한 대안으로 sleep 20충분할 수 있습니다.

다음은 현재 init 스크립트의 닫기 블록에서 사용중인 것입니다.

# 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를 지원하지 않는 이전 시스템을 에뮬레이션하는 경우에도 작동하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.