vkernel発掘体験記
vkernelを使ってみたい
実際に私のDragonflyBSDのバージョンでvkernelを使ってみたかったので,やってみた.
まず,DragonflyBSDのマニュアルを参考にして実行を試みました.
vknetd
vkernel
が,-bash: vkernel: コマンドが見つかりません というエラーが.
流石にvkernelってコマンドはないのかぁ.
vkernelを利用できるようにする道のりは長そうです.
vkernelを起動する
とりあえず,手当たり次第にvkernelとつくものがないか調べてみた
$ find / -name "vkernel"
/usr/obj/usr/src/sys/VKERNEL64/usr/src/sys/dev/virtual/vkernel
/usr/src/test/vkernel
/usr/src/sys/dev/virtual/vkernel
/usr/src/etc/rc.d/vkernel
/build/usr.obj/usr/src/sys/VKERNEL64/usr/src/sys/dev/virtual/vkernel
/etc/rc.d/vkernel
(。´・ω・)ん? なんか”いかにも”なファイルがあったような..
/etc/rc.d/vkernel ←!!?!?!?!!?!?!!?
当たり前かもしれないけど,ちゃんと起動スクリプトにvkernelの準備がありました.
デフォルトの起動はどうなっているか見ると,まぁNOになっています.
$ emacs /etc/defaults/rc.conf
...
vkernel_enable="NO" # Set to YES to enable starting of vkernels
...
つまり実行するものがあれば,vkernelがすぐ使えるということですね.
その肝心の中身がないのだけれど..
起動スクリプトから機能を見てみる
$ cat /etc/rc.d/vkernel
簡単にまとめると,
①vkernelバイナリを要求
②メモリサイズを設定
③ルートイメージ設定
④daemon経由で起動する
特に①のvkernelバイナリがあれば使えるということです.
開発者としては,/bootにバイナリがあることを想定しているようです.
#vkernel_bin="/boot/kernel.VKERNEL64"
じゃあ,実際にカーネルをビルドして置いておこう
バイナリがない
cd /usr/src
sudo make buildkernel KERNCONF=VKERNEL64
結果
ちゃんとOSとソースのバージョンは揃えようね!(一敗)
-------------------------------------------------------------
>>> Kernel build for VKERNEL64 completed
-------------------------------------------------------------
$ ls /boot | grep "kernel.VKERNEL64"
$
うーーん,結果のバイナリはkernel.VKERNEL64って名前じゃないのか..?
とりあえず,手当たり次第にVKERNEL64とつくファイルを探してみた
$ find / -name "VKERNEL64"
/usr/obj/usr/src/sys/VKERNEL64
/usr/src/sys/config/VKERNEL64
/build/usr.obj/usr/src/sys/VKERNEL64
直接kernel.VKERNEL64はなかったが,/usr/obj/usr/src/sys/VKERNEL64が怪しいらしい.
この中にはビルド結果のファイルが置かれています.
そして中に.doneというファイルがあり,それがビルド完了を示すファイルです.
ビルドも確実に成功している,後はこの中にバイナリもあるはず..
サイズでソートして大きいものがバイナリのはず..
$ ls -lhS /usr/obj/usr/src/sys/VKERNEL64 | head -10
total 255746
-rwxr-xr-x 1 root wheel 44M kernel.debug
-rwxr-xr-x 1 root wheel 5.5M kernel.stripped
...
上位2つのこのファイルが候補だが,名前的にkernel.debugではないでしょう.
vkernelバイナリを使って実行する
とりあえずそのままkernel.strippedを実行してみた
$ /usr/obj/usr/src/sys/VKERNEL64/kernel.stripped
kernel.stripped: vm.vkernel_enable is 0, must be set to 1 to execute a vkernel!
vm.vkernel_enableの値を1にすれば実行できる!!
$ sudo sysctl vm.vkernel_enable=1
vm.vkernel_enable: 0 -> 1
勝ったな👍
$ /usr/obj/usr/src/sys/VKERNEL64/kernel.stripped
Usage: /usr/obj/usr/src/sys/VKERNEL64/kernel.stripped [-hsUvdt] [-c file] [-e name=value:name=value:...]
[-i file] [-I interface[:address1[:address2][/netmask]]] [-l cpulock]
[-m size] [-n numcpus[:lbits[:cbits]]]
[-p file] [-r file]
あとは,kernel.strippedを/boot/kernel.VKERNEL64として置いて,vkernel_enableをONにするだけ!
$ sudo service vkernel start
Starting virtual kernels: destroy_machine.
起動したぁああああああ‼️‼️‼️
が,ここで問題が発生.プロセスがない.
$ ps aux | grep kernel.VKERNEL64
$
ログを見ると,こんな表示が.
Using memory file: /var/vkernel/memimg.000000 kernel.VKERNEL64: Unable to mmap() kernel virtual memory!: Operation not supported
これについて格闘していたら,とんでもない事実にたどり着きました.
vkernelはサポートが削除されていた
ソースコードを調べると,vkernelはMAP_VPAGETABLEという特殊なmmapフラグを使用していました.
しかし,sys/mman.hには,
/*
* NOTE! MAP_VPAGETABLE is no longer supported and will generate a mmap()
* error.
*/
さらにvm_mmap.cでは
/*
* Virtual page table support has been removed and now always
* returns EOPNOTSUPP.
*/
if (flags & MAP_VPAGETABLE)
return (EOPNOTSUPP);
つまり,実行すると意図的にエラーになるようにされていたのです.
2021年のコミット
2021年1月7日のMatthew Dillon 氏のコミット
kernel - Remove MAP_VPAGETABLEには,
This will break vkernel support for now
と書かれていました.
さらに,
We will need actual hardware mmu virtualization to get the vkernel working again.
とも書かれており,ソフトウェアページテーブルを利用していた従来のvkernelは,VMシステムの変更と両立できなくなったため,一旦停止されたようです.
なので,それ以降のDragonflyBSDの6.0 系以降では vkernel が動作しなくなっています.
まとめ
最新バージョンでは変態的特徴のあるvkernelが使えないのは残念でした.この上でDragonflyBSDのシステムで遊んでみたかったので.
for nowという書き方なので,いつか復活することを望んで待ちます🤓
