TL;DR
- VirtualBox と Vagrant 環境で Rocky Linux 10 公式 Box を使おうとすると、仮想マシンの動作が異常に遅い、あるいは起動そのものに失敗する場合がある
- 原因として以下の二つの要因がある
- 原因1:
- Rocky Linux 10 公式 Box では IOAPIC が無効になっている
- 対処は
Vagrantfileに IOAPIC を有効にする設定を追加する
- 原因2:
- Intel CPU 第12世代(Alder Lake)以降ではCPUの省電力機能により VirtualBox の動作が遅くなる場合がある
- 対処は
powercfg /powerthrottling disableコマンドを使って VirtualBox 実行時の省電力機能を無効化する
対処方法
対処1: 仮想マシンのIOAPICを有効にする
-
Vagrantfileに以下の設定を追加する
config.vm.provider :virtualbox do |v|
v.customize ["modifyvm", :id, "--ioapic", "on"]
end
対処2: VirtualBox に対して Intel CPU の省電力制御を無効化する
- 管理者権限で以下のコマンドを実行する
- AMD CPUでは不要
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxHeadless.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VirtualBoxVM.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VirtualBox.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetDHCP.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetNAT.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxSVC.exe'
以降は詳細についての説明
問題の詳細
前提環境
- ホストOS: Windows 11
- (環境1) Intel Core Ultra 7 165U
- (環境2) AMD Ryzen 9 8945HS
- いずれも Hyper-V/WSL2 を有効化
- VirtualBox-7.2.2
- Vagrant-2.4.9
- 仮想マシンOS
事象: 仮想マシン起動処理が非常に遅い
VirtualBox + Vagrant 上で Rocky Linux 9.6 で作っていた環境を Rocky Linux 10.0 に置き換えようとしたところ、vagrant.exe up の起動がいつまでたっても完了しないという事象が発生した。別の環境では一応起動はできたものの完了まで非常に時間がかかり、とても使い物にならない。
具体的な時間として、ほぼ最低限のVagrantfile構成で起動時間を計測してみた結果が以下の通り。
表1: 問題発生時の起動時間
| 仮想マシン | 環境1: Intel CPU | 環境2: AMD CPU |
|---|---|---|
| Rocky 9.6 | 2m24s | 42s |
| Rocky 10.0 | 起動失敗(5m18s) | 4m31s |
「起動失敗」の事象としては以下の通り
-
vagrant.exe up実行後OSのブート処理が非常に遅く、5分程度経過後vagrant.exe upコマンドがタイムアウト(vm.config.boot_timeout)で終了する - 仮想マシン内ではOSのブート処理は継続するが、30分程度経っても完了せず、Emergency mode で停止する
起動時間は以下のコマンドのタイムスタンプで計測。
date; vagrant.exe up; date
計測用に使った Vagrantfile の内容は以下の通り
Rocky 9.6 Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "rockylinux/9"
config.vm.box_version = "6.0.0"
config.vm.provider :virtualbox do |v|
v.memory = 2048
end
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.define "rocky96vb" do |rocky96vb|
rocky96vb.vm.hostname = "rocky96vb"
rocky96vb.vm.network "private_network", ip: "192.168.56.61"
rocky96vb.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2261
rocky96vb.vm.provider :virtualbox do |v|
v.name = "rocky96vb"
end
end
end
Rocky 10.0 Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "rockylinux/10"
config.vm.box_version = "0.0.0"
config.vm.provider :virtualbox do |v|
v.memory = 2048
end
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.define "rocky10vb" do |rocky10vb|
rocky10vb.vm.hostname = "rocky10vb"
rocky10vb.vm.network "private_network", ip: "192.168.56.62"
rocky10vb.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2262
rocky10vb.vm.provider :virtualbox do |v|
v.name = "rocky10vb"
end
end
end
原因と対処1: IOAPIC の設定
事象の切り分け
事象発生原因を切り分けていく中で以下の事実が確認できた
- Vagrant Box は使わず自分で Rocky Linux 10 インストールイメージを使って仮想マシンを新規作成した場合、起動時間は遅くならない
- AlmaLinux 10 公式 Boxでは、やや時間はかかるものの起動はできる
ということから、どうやら Rocky Linux 10.0 公式Box 固有の問題っぽいと環境差異を調べたところ、Rocky 10.0 Box の場合のみ IOAPIC が有効になっていないことが判明した。
Rocky 9.6 と Rocky 10.0 の Box の OVFファイルを確認してみると確かに以下の差異がある
$ grep IOAPIC rockylinux-VAGRANTSLASH-9/6.0.0/amd64/virtualbox/box.ovf
<IOAPIC enabled="true"/>
$ grep IOAPIC rockylinux-VAGRANTSLASH-10/0.0.0/amd64/virtualbox/box.ovf
$
対処1 対処結果
ということで、Rocky 10.0 の Vagrantfile に IOAPIC を有効にする設定を追加して起動時間を計測した結果が以下の通り。
環境1(Intel CPU)では少なくとも起動失敗してしまう事象は解消された。また環境2(AMD CPU)では Rocky 9.6 のときと大差ない程度には改善した。
表2: IOAPIC 設定追加時の起動時間
| 仮想マシン | 環境1: Intel CPU | 環境2: AMD CPU |
|---|---|---|
| Rocky 9.6 | 2m24s | 42s |
| Rocky 10.0 | 起動失敗(5m18s) | 4m31s |
| Rocky 10.0 (IOAPIC有効化) | 4m09s | 59s |
Rocky 10.0 (IOAPIC有効化) Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "rockylinux/10"
config.vm.box_version = "0.0.0"
config.vm.provider :virtualbox do |v|
v.customize ["modifyvm", :id, "--ioapic", "on"]
v.memory = 2048
end
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.define "rocky10io" do |rocky10io|
rocky10io.vm.hostname = "rocky10io"
rocky10io.vm.network "private_network", ip: "192.168.56.63"
rocky10io.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2263
rocky10io.vm.provider :virtualbox do |v|
v.name = "rocky10io"
end
end
end
原因と対処2: Intel CPU の省電力制御
事象の切り分け
対処1で起動はできたものの、それでも環境1(Intel CPU)の起動時間が遅すぎてまだ使い物になるとは言えない。
さらに切り分けてみると、同じ仮想マシンでも VirtualBox の GUI から直接起動すると起動が早いことが確認できた。vagrant.exe upはヘッドレス起動しており、どうやら通常起動(GUI起動)とヘッドレス起動(デタッチモード)で差異が出るらしい。
この差異を、Rocky 10.0 (IOAPIC有効化) で作成した仮想マシンを直接 VBoxManage.exe startvm コマンドで起動して起動時間を計測した。この場合の起動時間はコンソールにログインプロンプトが出るまでの時間を目視で計測したもの。
表3: 起動コマンドの違いによる起動時間の差異
| 起動コマンド | 環境1: Intel CPU | 環境2: AMD CPU |
|---|---|---|
通常起動VBoxManage.exe startvm VM名
|
37s | 33s |
ヘッドレス起動VBoxManage.exe startvm VM名 --type headless
|
1m53s | 32s |
(参考) vagrant.exe up
|
4m09s | 59s |
この事象について調査してみたところ、以下の類似事象の情報が見つかった。
- CLI startvm headless hangs with Fedora and Redhat guests
- Headless boot from command line never completes with some guest OS
要約すると以下の通り。
- Intel CPU の第12世代(Alder Lake)以降のハイブリッドアーキテクチャでは省電力のために P-core(高性能コア) と E-core(高効率コア) の二種類が使い分けられている
- VirtualBox の仮想マシンを通常起動(GUI起動)した場合は P-core、ヘッドレス起動したときは E-core が使用される
- RHEL系のOSの仮想マシンを E-core で動作させるとなぜかハングアップしたり動作が遅かったりする
- Hyper-V が有効になっていると問題が発生する。Hyper-V を完全に無効化すると問題は発生しない
-
powercfg /powerthrottling disableコマンドで VirtualBox 実行時の省電力制御を無効化し、常に P-core を使うように設定すると問題は解消する
今回の自分の環境でも Hyper-V/WSL2が有効になっているが、自分の使い方では Hyper-V/WSL2 は並行して利用したいので、Hyper-V を無効化する対処は除外した。
対処用スクリプト
上記リンク先の記載に従って、以下のスクリプトを作成して VirtualBox 実行の省電力制御を無効化する。
VirtualBoxに対し省電力制御を無効化するスクリプト
# Priviledge escalation
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
exit;
}
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxHeadless.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VirtualBoxVM.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VirtualBox.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetDHCP.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetNAT.exe'
powercfg /powerthrottling disable /path 'C:\Program Files\Oracle\VirtualBox\VBoxSVC.exe'
Write-Host 'powercfg /powerthrottling list'
powercfg /powerthrottling list
Write-Host 'ENTER to close'
Read-Host
実行方法
powershell.exe -File powercfg-disable.ps1
実行するとUAC制御ダイアログが表示される。
実行後、設定結果がウィンドウに表示されるので、確認したら Enter を押してウィンドウを閉じる。
確認が不要な場合はWrite-Host 'powercfg /powerthrottling list'以降の行をすべて削除しても良い。
対処2 対処結果
上記スクリプトを実行してVirtualBoxの省電力制御を無効化した結果の計測時間は以下の通り。
この対処により Intel CPU の起動時間が AMD CPU と同程度に改善され、どちらの環境でも十分短い時間で仮想マシンが起動できるようになった。
Rocky 10.0 では、対処1のIOAPIC有効化を行っていない場合でも起動失敗は解消するが、やはり実用的な起動時間ではないため、対処1、対処2の両方が必要である。
また Rocky 9.6 の起動時間も大きく改善した。今までは何となく「性能の良いPCなのに遅いなあ」程度にしか思っていなかったが、実は本来の性能が十分出ていなかったらしい。
なお表には記載していないが、AlmaLinux でも同様に起動時間が短縮されることを確認している。
表4: VirtualBox省電力制御無効化後の起動時間
| 仮想マシン | 環境1: Intel CPU (デフォルト) |
環境1: Intel CPU (省電力無効化設定) |
環境2: AMD CPU |
|---|---|---|---|
| Rocky 9.6 | 2m24s | 46s | 42s |
| Rocky 10.0 | 起動失敗(5m18s) | 5m30s | 4m31s |
| Rocky 10.0 (IOAPIC有効化) | 4m09s | 62s | 59s |
表5: 起動コマンドの違いによる起動時間の差異(Rocky 10.0 (IOAPIC有効化))
| 起動コマンド | 環境1: Intel CPU (デフォルト) |
環境1: Intel CPU (省電力無効化設定) |
環境2: AMD CPU |
|---|---|---|---|
通常起動VBoxManage.exe startvm VM名
|
37s | 27s | 33s |
ヘッドレス起動VBoxManage.exe startvm VM名 --type headless
|
1m53s | 24s | 32s |
(参考) vagrant.exe up
|
4m09s | 62s | 59s |
設定をリセットするスクリプト
もし設定を元に戻したいときは以下のスクリプトを同様に実行する。
# Priviledge escalation
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath'`"";
exit;
}
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VBoxHeadless.exe'
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VirtualBoxVM.exe'
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VirtualBox.exe'
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetDHCP.exe'
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VBoxNetNAT.exe'
powercfg /powerthrottling reset /path 'C:\Program Files\Oracle\VirtualBox\VBoxSVC.exe'
Write-Host 'powercfg /powerthrottling list'
powercfg /powerthrottling list
Write-Host 'ENTER to close'
Read-Host
powershell.exe -File powercfg-reset.ps1
結論まとめ
- Rocky Linux 10 公式 Boxを使う場合は、対処1の通り仮想マシン設定で IOAPIC を有効にする必要がある
- Intel CPU を使っている場合、対処2の VirtualBox 省電力制御を無効化する必要がある。この改善効果は Rocky Linux 10 以外でも有効である
以上
