Tôi muốn giới thiệu một cách tiếp cận tinh vi hơn bao gồm một công việc mới bắt đầu, một kịch bản bắt đầu và dừng lại. Ví dụ tôi đang sử dụng Windows XP, vì thư mục chính của tôi cho phép sử dụng tombert ... mà bạn nên thay đổi cho phù hợp. Nó có lợi thế của bất cứ điều gì bạn làm (khởi động lại, tắt máy, nhấn nút nguồn) nó xử lý tốt máy ảo của bạn .
Đầu tiên, công việc mới bắt đầu, đưa vào /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
Công việc mới bắt đầu khởi động máy ảo trong runlevel 2 (ở chế độ đồ họa) và trong trường hợp của tôi, nó tăng mức độ ưu tiên với nice
. Để tắt máy ảo, tôi cần "vô hiệu hóa" việc chấm dứt khởi động bằng cách sử dụng kill signal SIGCONT
câu lệnh. Điều này khiến máy ảo chạy lúc đầu (tránh mặc định SIGTERM
). Sau 120 giây, SIGKILL
dù sao đi nữa. Thay vào đó tôi đang chạy winxpvm-stop.sh
kịch bản.
Lưu ý phụ 1: Các khổ thơ start on started runlevel [2]
và stop on starting runlevel [!2]
không hoạt động. Người ta phải đề cập cụ thể đến công việc rc
.
Lưu ý phụ 2: Điều gì cũng khó hiểu từ hướng dẫn sử dụng mới bắt đầu: Đoạn kill signal
thơ chỉ định tín hiệu được gửi sau 5 giây. Trong ví dụ này, tôi đặt nó từ SIGTERM
(mặc định) thành SIGCONT - nhưng thời gian chờ 5 giây tôi không thể thay đổi. Đoạn kill timeout
thơ chỉ định thời gian chờ mà sau đó SIGKILL
được gửi - tín hiệu mà người ta không thể thay đổi. Do đó, một cải tiến sẽ là xác định khổ thơ mới term signal
và term timeout
.
Ở đây tập lệnh bắt đầu 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
Vì tất cả các cài đặt, v.v. được thực hiện trong chế độ người dùng (vì thông tin đăng nhập của tôi là tombert ), ngay cả khi chạy bằng root, tôi thay đổi tài khoản thành tombert . Người dùng tất nhiên có thể được thay đổi trong cấu hình khởi động nhưng giải pháp này cho tôi tùy chọn khởi động / dừng máy ảo "bằng tay" từ bảng điều khiển.
Điều thú vị hơn là kịch bản tắt máy trong 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
Đầu tiên tôi làm tương tự như trong tập lệnh bắt đầu - Tôi đang thay đổi người dùng từ root sang tài khoản tombert của tôi . Bây giờ hãy xem chức năng dostop
. Đầu tiên tôi đang kiểm tra xem máy ảo có chạy không. Sau đó, tôi đang cố gắng "nhẹ nhàng" tắt máy bằng cách gửi tắt máy trực tiếp đến WinXP bằng cách sử dụng guestcontrol
. Ở đây bạn phải cung cấp thông tin đăng nhập cho tài khoản WinXP, trong trường hợp của tôi là tombert và mật khẩu. Windows shutdown
sẽ đóng một cách duyên dáng tất cả các ứng dụng và tắt nguồn hệ điều hành (thông thường). Sau đó cho phép kiểm tra trạng thái máy ảo liên tục bằng cách sử dụng showvminfo
. Làm điều này ít nhất 60 lần với thời gian chờ 1 giây (làm bất cứ điều gì bạn nghĩ là phù hợp ở đây) sẽ khiến máy ảo đủ thời gian để tắt máy một cách duyên dáng. Lưu ý rằng cuộc gọi đếnshowvminfo
cũng mất ít hơn một chút (ít nhất là trên máy tính của tôi) vì vậy điều này mang lại cho nó ~ 120 giây trong trường hợp của tôi. Nếu mọi thứ phanh chúng ta có thể tắt máy mạnh mẽ bằng cách sử dụng poweroff
câu lệnh.
Bạn cũng nên xem acpipowerbutton
, nhưng không sử dụng. Điều này là do nó không hoạt động đáng tin cậy. Nếu bạn đã đăng nhập vào Windows, hoặc thậm chí tệ hơn nhiều người dùng, Windows sẽ hiển thị hộp thoại tắt xác nhận ngăn hệ thống tắt máy. Đây cũng là lý do tại sao acpibutton
trong /etc/default/virtualbox
sẽ không hoạt động đáng tin cậy 100%. Ngoài ra, poweroff
sẽ tắt mạnh máy ảo - giống như một nút nguồn nhấn dài. Vì vậy, tốt nhất là đặt cái này thành trống:
Trích từ / 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=""
Để làm cho nó hoàn hảo, bạn có thể muốn thay đổi hành vi của nút nguồn:
Trích từ /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
...
...
Có một nhược điểm nhỏ còn lại. Khi máy ảo vẫn khởi động và dịch vụ điều khiển khách không hoạt động (trong máy ảo), nó sẽ không nhận được lệnh tắt máy. Một trường hợp hiếm hoi ... nhưng hãy nghĩ về nó.
Đó là nó, hy vọng nó sẽ giúp.
reboot
trong 12.10 cho biết "Khi được gọi bằng --force hoặc khi ở runlevel 0 hoặc 6, công cụ này sẽ tự gọi hệ thống khởi động lại (2) và khởi động lại hệ thống. Nếu không, điều này chỉ đơn giản gọi công cụ tắt máy (8) với những lý lẽ phù hợp. "; và trang man choshutdown
biết "Một khi TIME đã trôi qua, tắt máy sẽ gửi một yêu cầu đến daemon init (8) để đưa hệ thống xuống runlevel thích hợp."