호스트 컴퓨터가 종료되거나 다시 시작될 때 VirtualBox Windows에서 실행되는 게스트 VM을 정상적으로 종료하는 솔루션을 찾으려고합니다.
호스트가 종료되기 시작할 때 "save state"명령을 트리거하는 것이 가장 안전한 옵션이지만 VM이 상태 저장을 마치고 전원이 꺼질 때까지 호스트가 오래 기다릴 지 여부는 확실하지 않습니다.
누구나이 문제에 대한 강력한 해결책이 있습니까?
호스트 컴퓨터가 종료되거나 다시 시작될 때 VirtualBox Windows에서 실행되는 게스트 VM을 정상적으로 종료하는 솔루션을 찾으려고합니다.
호스트가 종료되기 시작할 때 "save state"명령을 트리거하는 것이 가장 안전한 옵션이지만 VM이 상태 저장을 마치고 전원이 꺼질 때까지 호스트가 오래 기다릴 지 여부는 확실하지 않습니다.
누구나이 문제에 대한 강력한 해결책이 있습니까?
답변:
비슷한 문제가 있었고 VirtualBox를 서비스로 실행하여 해결했습니다.
http://vboxvmservice.sourceforge.net/
VBoxVMService를 사용하면 시스템 종료 (저장 상태, 전원 끄기) 및 시작 방법을 선택할 수 있습니다. 서비스로 실행 중이므로 Windows는 시스템 종료 프로세스 중에 자동으로 종료 될 때까지 기다립니다.
불행히도 VirtualBox GUI를 통해 VM을 시작한 경우에는 불가능한 것 같습니다. GUI가 호스트 종료 이벤트를 포착하여 반응하더라도 VirtualBox 서비스가 종료됩니다. https://forums.virtualbox.org/viewtopic.php?p=278668#p278668
그래픽 콘솔이 필요하지 않은 경우 VBoxHeadlessTray 또는 VBoxVMService를 사용하는 것이 좋습니다. 둘 다 Windows 호스트 종료 및 재시작시 자동 저장 및 재개를 지원합니다.
VirtualBox 5.0에는 "분리 가능한 UI" 시작 모드가 도입되었습니다 . 이 모드는 별도의 UI 프로세스로 헤드리스 VM을 시작합니다. 그래도 그래픽 성능이 저하되고 3D 가속은 아직 지원되지 않습니다. 그러나 이것은 나중에 VBoxHeadlessTray와 결합 될 수 있습니다 (VBoxHeadlessTray는 아직 5.0을 지원하지 않습니다.) VBoxHeadlessTray GitHub 리포지토리 및 VirtualBox 5 지원 추가를위한 해당 GitHub 풀 요청에 대한 링크 .
편집 : VBoxVmService는 버전 5.0부터 새로운 분리 가능 모드를 지원하지 않습니다 . 만 헤드리스 지금까지. 이에 대한 기능 요청 을 추가했습니다 .
시작 메뉴 전원 버튼 대신 3 개의 배치 스크립트가 있습니다.
do_shutdown.bat (10 초 대기 시간이있는 종료 PC, vm의 10 초 시간을 savestate에 제공하지 않고 10 초 내에 종료를 취소 할 수 있도록합니다. vm이 종료 된 후 카운트 다운이 시작됨)
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /s /t 10
do_reboot.bat (vm이 종료 된 직후 재부팅)
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /r /t 0
do_cancel.bat (10 초 대기 기간 내에 pc-shutdown을 취소 할 수 있습니다. 그런 다음 do_shutdown.bat로 종료되었으므로 vm을 다시 시작합니다)
shutdown /a
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Minimal" --type headless
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Server" --type headless
대신 savestate
다음 중 하나를 사용할 수도 있습니다.
poweroff - pulls the plug
(probably not a good idea...)
acpipowerbutton - presses the power off button for a clean shutdown
("The system is going down for power off NOW!" to all consoles)
acpisleepbutton - tells the os to go to sleep
(probably just as bad as poweroff)
파티에 늦어서 미안해 약간의 commandline-foo가 필요하지만 이것에 대한 정확한 대답이 있습니다. 자세한 내용은이 게시물을 참조하십시오 : https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540
찾고있는 명령은 다음과 같습니다.
"C : \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe"setextradata "VM NAME"GUI / DefaultCloseAction 종료
이것은 여러 VM에서 사용하는 창이며 창을 닫고 안전한 종료를 자동으로 시작합니다. Windows를 종료하고 모든 것을 닫으려고 시도하면 이러한 프로세스가 완료 될 때까지 기다립니다.
비슷한 질문이 있었고이 페이지를 찾았습니다. 테스트를 위해 많은 VM이 있고 일반적으로 VirtualBox UI에서 실행할 다른 VM을 선택하기 때문에 VirtualBox를 서비스로 실행하고 싶지 않습니다. 컴퓨터를 종료하면 각 VM의 상태를 수동으로 저장하는 것이 번거 롭습니다. 이 경우 스크립트를 사용하여 실행중인 모든 VM을 저장하는 것이 실용적인 솔루션 인 것 같습니다. Daniel F의 답변을보다 일반적으로 만들기 위해, 실행중인 모든 VM의 상태를 명시 적으로 명명하지 않고 자동으로 저장하는이 스크립트를 작성했습니다.
Windows 용 saveRunningVMs.bat :
set VBoxManageEXE="%ProgramFiles%\Oracle\VirtualBox\VBoxManage.exe"
set ListRunningVMS=%VboxManageEXE% list runningvms
for /f tokens^=2^,4^ delims^=^" %%p in ('%ListRunningVMS%') do %VBoxManageEXE% controlvm %%p savestate
echo all vms saved, you can shutdown now.
rem shutdown /s /t 10
Linux의 경우 saveRunningVMs.sh :
#!/bin/bash
vboxmanage list runningvms | while read line; do
#echo "VBoxManage controlvm $uuid savestate;"
echo $line
if [[ $line =~ \{(.*)\} ]]
then
vboxmanage controlvm ${BASH_REMATCH[1]} savestate
fi
done
실행중인 모든 VirtualBox VM을 일시 중단하는 Python 스크립트를 만든 다음 로그 아웃시 스크립트를 예약 된 작업으로 실행하도록 시스템을 설정했습니다.
이 방법이 얼마나 안정적인지 잘 모르겠습니다. 다른 사람들이 언급했듯이 시스템이 Winlogon 7002 작업이 완료되기를 기다리는 시간에는 제한이 있습니다. 그러나 개인적으로 4GB 이상의 전체 VM RAM에서 여러 개의 실행중인 VM에서도 사용 가능한 저장 상태를 제공하는 데 아무런 문제가 없었습니다.
설정 단계는 다음과 같습니다.
python.exe
예를 들어,c:\Python27\python.exe
C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
이제 VirtualBox VM은 로그 아웃 / 재시작 / 종료시 일시 중단되어야합니다.
종료를 수행하는 python 스크립트는 다음과 같습니다.
# A script to suspend all running VirtualBox VMs
import os
import subprocess
import sys
class VM(object):
def __init__(self, name, uuid):
self.name = name
self.uuid = uuid
def __repr__(self):
return "VM(%r,%r)" % (self.name, self.uuid)
class VBoxRunner(object):
def __init__(self):
program_files = os.environ["ProgramW6432"]
vbox_dir = os.path.join(program_files, "Oracle", "VirtualBox")
self.vboxmanage_filename = os.path.join(vbox_dir, "VBoxManage.exe")
def vbox_run(self, *args):
subprocess.check_call([self.vboxmanage_filename] + list(args))
def vbox_run_output(self, *args):
return subprocess.check_output([self.vboxmanage_filename] + list(args))
def list(self, running=True):
if running:
list_cmd = "runningvms"
else:
list_cmd = "vms"
return [self.parse_vm_list_entry(x) for x in self.vbox_run_output("list", list_cmd).strip().split("\n")]
def suspend_all(self):
success = True
stopped_some_vms = False
vms = self.list(running=True)
for vm in vms:
if vm is None:
continue
# noinspection PyBroadException
try:
self.suspend_vm(vm)
except:
success = False
else:
stopped_some_vms = True
if not stopped_some_vms:
self.message("No running vms")
return success
@staticmethod
def parse_vm_list_entry(x):
""":type x: str"""
if not x.startswith('"'):
return None
end_pos = x.find('"', 1)
if end_pos == -1:
return None
name = x[1:end_pos]
assert x[end_pos + 1: end_pos + 3] == " {"
assert x.endswith("}")
uuid = x[end_pos + 2:]
return VM(name, uuid)
@staticmethod
def message(msg):
print >>sys.stderr, msg
def suspend_vm(self, vm):
assert isinstance(vm, VM)
self.vbox_run("controlvm", vm.uuid, "savestate")
def main():
vr = VBoxRunner()
success = vr.suspend_all()
if not success:
sys.exit(1)
if __name__ == "__main__":
main()