Tutup mesin virtualbox dengan aman pada host reboot

8

Saya menjalankan Windows 7 di dalam Virtualbox di Ubuntu 11.10. Semuanya bekerja dengan baik. Saya menjalankannya saat startup, tetapi saya memiliki masalah dengan reboot.

Ketika saya mengetik sudo reboot nowkeadaan virtual Windows 7 tidak disimpan. Setelah reboot, virtualbox dimulai, tetapi bukannya menjalankan Windows saya mendapatkan menu boot crash 7 Windows dan windows boot lagi.

Apakah ada opsi bahwa Ubuntu dapat mengirim beberapa sinyal ke kotak virtual untuk menutup instance dengan aman sebelum host reboot?

takeshin
sumber

Jawaban:

6

Jika Anda benar-benar perlu mematikan ketika mesin virtual di Virtual Box sedang berjalan, Anda dapat menentukan skrip Anda sendiri untuk shutdown manual di mana Anda menempatkan perintah untuk menyimpan status mesin sebelum proses mematikan dimulai:

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

Atau Anda juga bisa membuat skrip yang selalu berjalan saat shutdown .

Takkat
sumber
4

Jika Anda menggunakan sudo rebootprogram diberi sinyal mematikan untuk mengakhiri secara otomatis tanpa memberikan waktu aplikasi untuk bertindak pada situasi tersebut. Ini bukan bug, itu selalu bekerja dengan cara yang sama dan itu adalah perilaku yang diharapkan.

Ada pertanyaan serupa di mana Anda dapat melihat perintah yang diberikan saat Anda menekan shutdown, reboot, suspend, dll tombol pada menu pengguna, solusi tersebut harus meminta Anda apa yang harus dilakukan ketika mencoba untuk menutup jendela dengan aplikasi yang berjalan dan yang lebih (di kasus Anda) untuk sudo shutdownpendekatan. Silahkan lihat

Bruno Pereira
sumber
Apakah reboot baru-baru ini menjadi lebih sopan? Halaman manual untuk rebootdi 12.10 mengatakan "Ketika dipanggil dengan --force atau ketika di runlevel 0 atau 6, alat ini memanggil reboot (2) system call sendiri dan langsung reboot sistem. Jika tidak, ini hanya memanggil tool shutdown (8) dengan argumen yang sesuai. "; dan halaman manual untuk shutdownmengatakan "Setelah TIME berlalu, shutdown mengirimkan permintaan ke daemon init (8) untuk membawa sistem ke runlevel yang sesuai."
echristopherson
4

Saya akan merekomendasikan pendekatan yang lebih canggih termasuk pekerjaan pemula, skrip start dan stop. Sebagai contoh saya menggunakan Windows XP, karena direktori home saya menggunakan tombert ... yang harus Anda ubah. Ini memiliki keuntungan dari apa pun yang Anda lakukan (reboot, shutdown, menekan tombol power) yang menangani mesin virtual Anda dengan baik .

Pertama pekerjaan pemula, masukkan /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

Pekerjaan pemula memulai mesin virtual di runlevel 2 (yang dalam mode grafis), dan dalam kasus saya ini meningkatkan prioritas dengan nice. Untuk mematikan mesin virtual dengan baik, saya perlu "menonaktifkan" pengakhiran pemula menggunakan kill signal SIGCONTpernyataan. Ini membuat mesin virtual berjalan pada awalnya (menghindari default SIGTERM). Setelah 120 detik, SIGKILLbagaimanapun mengirim. Sebaliknya saya menjalankan winxpvm-stop.shskrip.

Catatan-Sisi 1: bait start on started runlevel [2]dan stop on starting runlevel [!2]tidak bekerja. Seseorang harus secara khusus menyebutkan pekerjaan itu rc.

Catatan Samping 2: Yang membingungkan juga dari manual pemula: kill signalStanza menentukan sinyal yang dikirim setelah 5 detik. Dalam contoh ini saya mengaturnya dari SIGTERM(default) ke SIGCONT - tetapi batas waktu 5 detik saya tidak dapat berubah. The kill timeoutbait menentukan batas waktu yang SIGKILLdikirim - yang sinyal seseorang tidak bisa berubah. Oleh karena itu perbaikan adalah untuk mendefinisikan bait baru term signaldan term timeout.

Di sini skrip start 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

Karena semua pengaturan dll dilakukan dalam mode pengguna (karena login saya adalah Tombert ), bahkan ketika dijalankan sebagai root saya mengubah akun ke Tombert . Pengguna tentu saja dapat diubah dalam konfigurasi pemula tetapi solusi ini memberikan saya pilihan untuk memulai / menghentikan mesin virtual "dengan tangan" dari konsol.

Yang lebih menarik adalah skrip shutdown di 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

Pertama saya melakukan hal yang sama seperti pada skrip awal - saya mengubah pengguna dari root ke Tombert akun saya . Sekarang mari kita lihat fungsinya dostop. Pertama saya memeriksa apakah mesin virtual bahkan berjalan. Kemudian saya mencoba "softly" shutdown dengan mengirimkan shutdown langsung ke WinXP menggunakan guestcontrol. Di sini Anda harus memberikan kredensial untuk akun WinXP, yang dalam kasus saya adalah Tombert dan kata sandi. Windows shutdownakan menutup semua aplikasi dengan anggun dan mematikan sistem operasi (biasanya). Kemudian mari kita periksa status mesin virtual terus menggunakan showvminfo. Melakukan ini setidaknya 60 kali dengan batas waktu 1 detik (melakukan apa pun yang menurut Anda tepat ada di sini) harus meninggalkan mesin virtual cukup waktu untuk mematikan dengan anggun. Perhatikan bahwa panggilan keshowvminfojuga membutuhkan sedikit kurang dari satu detik (setidaknya di komputer saya) jadi ini memberi ~ 120 detik dalam kasus saya. Jika semuanya mengerem, kami dapat mematikan paksa menggunakan poweroffpernyataan.

Anda juga harus melihat acpipowerbutton, tetapi tidak digunakan. Ini karena tidak berfungsi andal. Jika Anda masuk ke Windows, atau bahkan lebih dari satu pengguna yang lebih buruk, Windows akan menampilkan dialog shutdown konfirmasi yang mencegah sistem shutdown. Ini juga alasan mengapa acpibuttondi /etc/default/virtualboxtidak akan bekerja 100% dapat diandalkan. Juga poweroffsecara paksa akan mematikan mesin virtual - sama seperti tombol power lama-tekan. Karena itu yang terbaik adalah mengosongkannya:

Kutipan dari / 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=""

Untuk membuatnya sempurna, Anda mungkin ingin mengubah perilaku tombol daya:

Kutipan dari /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
...
...

Ada satu kekurangan kecil yang tersisa. Ketika mesin virtual masih booting dan layanan kontrol tamu tidak menyala (di mesin virtual) itu tidak akan menerima perintah shutdown. Kasus yang jarang terjadi ... tapi pikirkanlah.

Itu dia, semoga membantu.

Tombert
sumber
Bekerja seperti pesona (tamu Windows XP), kecuali tampaknya membuang VERR_INVALID_PARAMETERdi sisi tuan rumah jika saya masuk melalui RDC sebagai pengguna yang diberikan dalam skrip, dan selanjutnya tamu terus berjalan.
echristopherson
Saya mencoba dengan keduanya, RDC asli dan dengan RDC di atas VirtualBox. Tidak ada kesalahan seperti itu. Mungkin terkait dengan virtualbox.org/ticket/8197
tombert
2

Ikuti jawaban ini untuk mengubah kebijakan sistem Anda untuk reboot

Anda tidak dapat merampingkan ini menjadi reboot. init.dSkrip AFAIK tidak akan berfungsi karena membutuhkan terlalu banyak waktu, tetapi Anda dapat menjalankan perintah seperti ini:

VBoxManage controlvm <vm> savestate&&reboot

di mana <vm>nama Mesin Virtual

Amith KK
sumber
1

Anda dapat mengirim permintaan penutupan ke mesin virtual dengan:

VBoxManage controlvm <vm_name> acpipowerbutton

Tetapi jika Anda melakukan ini dalam skrip init, skrip tidak boleh keluar sampai shutdown selesai. Kami mungkin dapat mendeteksi bahwa dengan polling file drive VM (.vdi) dengan lsofatau fuserdalam satu lingkaran. Atau sebagai solusi murah, sleep 20mungkin sudah cukup.

Inilah yang saya gunakan saat ini di blok dekat skrip init saya:

# 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

Di dekat bagian atas file yang saya definisikan:

VMDISKIMAGE="/home/$DAEMONUSER/VirtualBox VMs/$VMNAME/$VMNAME.vdi"

Ini mungkin sebenarnya tidak menutup aplikasi VirtualBox itu sendiri, tetapi menunggu VM menyelesaikan shutdown. Juga tidak berfungsi jika mesin virtual masih dalam proses booting (banyak sistem operasi mengabaikan tombol matikan selama fase ini), atau jika Anda meniru sistem lama tanpa dukungan ACPI.

joeytwiddle
sumber