bhyve
Table of Contents
truncate
前回目をつけておいたFreeBSD/amd64で、bhyveをやってみたい。これって、不自 由なqemuと看破したんだけど、何よりも有り難いと思うのは、qemuをパッケー ジから入れなくても済むことだ。どうせqemuを入れても使う石は、amd64か i386しかないからね(それ以外は、遅くて使用に耐えない、我ながら気が短か くなったものだ。歳のせいだな。)
専用に20GのDiskを増設したよ。で、ゲストOS用に、専用の仮想Diskを作成す る必要が有る。作成コマンドには、truncateってのを使うそうだ。ちと実験す る。
sakae@f64:/tmp $ truncate -s 4G mydisk sakae@f64:/tmp $ ls -lh mydisk -rw-r--r-- 1 sakae wheel 4.0G Jun 29 15:49 mydisk sakae@f64:/tmp $ df -h Filesystem Size Used Avail Capacity Mounted on /dev/da0s1a 22G 4.1G 16G 20% / devfs 1.0K 0B 1.0K 0% /dev tmpfs 384M 4.0K 384M 0% /tmp /dev/da1 19G 1.7G 16G 10% /opt sakae@f64:/tmp $ ls -s mydisk 0 mydisk
注目は、/tmpの下に4Gのファイルを作成出来てしまった事。張子の虎を作成するコマンドなのだな。
OpenBSD on bhyve
一番ターゲットにしたいのは、OpenBSDだ。何と言っても直接VMWareで扱おと すると、問題を起こしていたからね。たとえFreeBSDの中からでも、動けばオ ンノジだ。
起動は面倒だけど、2段階の手順を踏むそうだ。最初は、どこかで見た事があ るようなコマンドを叩いて、miniroot相当をロードするらしい。
# cat dev.map (hd0) /opt/OB75/disk.img (cd0) /opt/OB75/install75.iso # cat grub grub-bhyve -m dev.map -r cd0 -M 384M ob75
デバイスのマッピング・ファイルを用意して、それを引数にgrub-bhyveを起動 するとな。で、起動に成功したら、マニュアルで、bsd.rdとcom0を認識さるっ ぽい。
# ./grub Could not create VM ob75 Error in initializing VM
出鼻を挫かれた。幸先悪いぞ。これって、ひょっとしてリナの血が混ッている からでは、なかろうか? ちょいと中身を暴いてやる。今回は、得意のソース 読めは、繰り出しません。まあ、パッケージのソースを展開するのが、面倒な だけです(何せリナっぽいですから)。ktraceの姉妹品である、trussを使って、 システムコールをトレースしてみました。
# truss ./grub : read(10,"\ngrub-bhyve -m dev.map -r cd0 -"...,1024) = 43 (0x2b) fstatat(AT_FDCWD,"/usr/local/sbin/grub-bhyve",{ mode=-r-xr-xr-x ,inode=1289646,size=1058768,blksize=32768 },0x0) = 0 (0x0) vfork() = 1326 (0x52e) Could not create VM ob75 Error in initializing VM
なんか、フォークした後に問題が発生してるみたいですな。焦らずに、純正品 だけで、勝負してみますかね。急いては事を仕損じるですから。
FreeBSD on bhyve
そんな訳で、リナの影が全く無いやつです。まずはインストールって事で、-i でCDからのブート指定、-l で、その実体を指定。
# cat INS.sh /usr/share/examples/bhyve/vmrun.sh \ -c 1 \ -m 384M \ -t tap0 \ -d /opt/FB141/disk.img \ -i \ -I /opt/FB141/FreeBSD-14.1-RELEASE-amd64-disc1.iso \ freebsd-14.1
# ./INS.sh Launching virtual machine "freebsd-14.1" ... bhyveload: vm_create: Device not configured
何かOpenBSDの時と、様相は一緒だなあ。ならば、trussしましょ。
# truss ./INS.sh : read(10,"/usr/share/examples/bhyve/vmrun."...,1024) = 216 (0xd8) vfork() = 1361 (0x551) Launching virtual machine "freebsd-14.1" ... bhyveload: vm_create: Device not configured
/usr/share/examples/bhyve/vmrun.sh
shell scriptは接着剤なんで、部品を確認。冒頭に部品が列挙されてた。
LOADER=/usr/sbin/bhyveload BHYVECTL=/usr/sbin/bhyvectl FBSDRUN=/usr/sbin/bhyve
上のエラーから、bhyveloadの vm_create
でエラーしてると想像できるので、
該当部分を参照してみる。
bhyveload.c
vmname = argv[0]; need_reinit = 0; error = vm_create(vmname); if (error) { if (errno != EEXIST) err(1, "vm_create"); need_reinit = 1; }
指示した名前で、仮想マシンを作成しろ、だな。これが失敗してるって事は、 根本がそもそも動作していない。
念の為bhyveload(8)に出てたサンプルを実行。
# bhyveload -m 384M -d ./FreeBSD-14.1-RELEASE-amd64-disc1.iso test-vm bhyveload: vm_create: Device not configured
同じエラーですな。絞りこめてきました。
次なるは、 vm_create
を調査する事だな。
何処に定義されてるの? /usr/src/usr.sbin/bhyve*/* をgrepするも、みんな
平然と使っているだけですよ。こういう時は、Makefileを見て、変?なライブ
ラリィーを抱えこんでいないか調査。あるいは、
# ldd /usr/sbin/bhyveload /usr/sbin/bhyveload: libvmmapi.so.6 => /usr/lib/libvmmapi.so.6 (0x382fc37ae000) libc.so.7 => /lib/libc.so.7 (0x382fc47ea000) libutil.so.9 => /lib/libutil.so.9 (0x382fc5479000) [vdso] (0x382fc2b21000)
こんな方法でもいいかな。
vm_create
sakae@f64:/usr/src/lib/libvmmapi $ grep vm_create * vmmapi.c:vm_create(const char *name) vmmapi.c:vm_create_devmem(struct vmctx *ctx, int segid, const char *name, size_t len) vmmapi.h:void *vm_create_devmem(struct vmctx *ctx, int segid, const char *name, vmmapi.h:int vm_create(const char *name);
#define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) #define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) vm_create(const char *name) { /* Try to load vmm(4) module before creating a guest. */ if (modfind("vmm") < 0) kldload("vmm"); return (CREATE(name)); }
さて、この先、どうしよう? 無駄にこんなの確認したり。。。
sakae@f64:/usr/src/lib/libvmmapi $ sysctl hw.vmm : hw.vmm.create: beavis hw.vmm.destroy: beavis hw.vmm.maxcpu: 2 hw.vmm.trap_wbinvd: 0 hw.vmm.trace_guest_exceptions: 0 hw.vmm.ipinum: 252 hw.vmm.halt_detection: 1
そして、思い出したように。。。
# truss bhyveload -m 384M -d ./FreeBSD-14.1-RELEASE-amd64-disc1.iso test-vm : modfind("vmm") ERR#2 'No such file or directory' kldload("vmm") ERR#17 'File exists' __sysctlbyname("hw.vmm.create",13,0x0,0x0,0x35bc252734d4,7) ERR#6 'Device not configured'
for debug
母艦でのdebug環境を用意しておくか。CDイメージが有るので、そこから取り 出せばいいか。えと、どうやるんだっけ? ググる代わりにman mdconfigした ら、こんな技を紹介してくれたよ。これで、リナに馬鹿にされないな。
# mount -t cd9660 /dev/`mdconfig -f FreeBSD-14.1-RELEASE-amd64-disc1.iso` /mnt # cd / # tar jxf /mnt/usr/freebsd-dist/kernel-dbg.txz
base-dbg.txzはCDに未収録だったのでネットから取ってきて入れた。
kern_sysctl.c
カーネルサイドを閲覧。
sys___sysctlbyname(struct thread *td, struct __sysctlbyname_args *uap) { size_t rv; int error; error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old, uap->oldlenp, uap->new, uap->newlen, &rv, 0, 0); if (error != 0) return (error); if (uap->oldlenp != NULL) error = copyout(&rv, uap->oldlenp, sizeof(rv)); return (error); }
それから、エラーの名前をsys/*.h から、探し出しておく。
errno.h:#define ENXIO 6 /* Device not configured */
で、カーネル内部の動きを確認したいんだけど、それにはゲストOSとして FreeBSDが必要だ。qemuを入れるのも癪だな。
test
んで、思いついたのは、32BitのFreeBSDに、その環境が有るじゃん。供試品が 必要だな。/usr/sbin中で、sysctlbynameを使っているアプリは無いかな。 実害の無さそうなのがヒットしたんで、取りあえず確認。
sakae@f64:~ $ gdb -q pstat Reading symbols from pstat... Reading symbols from /usr/lib/debug//usr/sbin/pstat.debug... (gdb) b sysctlbyname Breakpoint 1 at 0x3a80 (gdb) r -hT Starting program: /usr/sbin/pstat -hT Breakpoint 1, sysctlbyname (name=0x10222fb "kern.maxfiles", oldp=0x7fffffffe8f8, oldlenp=0x7fffffffe8d0, newp=0x0, newlen=0) at /usr/src/lib/libc/gen/sysctlbyname.c:43 43 if (__predict_true(strncmp(name, "user.", 5) != 0)) {
on OpenBSD
sysctl(3)
[ENXIO] If the mib is a sparsely populated array, this error may be returned instead.
mibが疎な配列の場合、代わりにこのエラーが返されることがある。と、deepL は、翻訳してくれたぞ。ちょいと頭の中が混乱してるわい。
on FreeBSD/i386
(gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x010383fc in sys___sysctl at /usr/src/sys/kern/kern_sysctl.c:2325 2 breakpoint keep y 0x0103888c in sys___sysctlbyname at /usr/src/sys/kern/kern_sysctl.c:2397
これではブレークしないなあ? truss pstat -hT では、ちゃんと
__sysctl("sysctl.name2oid vm.swap_info",2,0xffbfe18c,0xffbfe104,0x400c63,12) = 0 (0x0) __sysctl("vm.swap_info.0",3,0xffbfe114,0xffbfe10c,0x0,0) = 0 (0x0) __sysctlbyname("kern.devname",12,0x20621795,0xffbfe0cc,0xffbfe0d0,8) = 0 (0x0) __sysctl("vm.swap_info.1",3,0xffbfe114,0xffbfe10c,0x0,0) ERR#2 'No such file or directory'
出てくるんだけどな。これ以上の深入りは止めておこう。
other way
そもそもカーネル側を調べたいってのは、エラーの現場を現行犯逮捕したいか ら。多分ハードの要件が有るはずなんで、原点に返ってハンドブックを確認。
The easiest way to tell if an Intel or AMD processor supports bhyve is to run dmesg or look in /var/run/dmesg.boot for the POPCNT processor feature flag on the Features2 line for AMD® processors or EPT and UG on the VT-x line for Intel® processors.
vmm.koって事で、その在処を探すと、/sys/amd64/vmm/
sakae@f64:/sys/amd64/vmm/intel $ grep ENXIO * vmx.c: return (ENXIO); vmx.c: return (ENXIO); vtd.c: return (ENXIO); vtd.c: return (ENXIO);
OSからしたら、ドライバーの扱いなのか。vmx.c
/* CPUID.1:ECX[bit 5] must be 1 for processor to support VMX */ if (!(cpu_feature2 & CPUID2_VMX)) { printf("vmx_modinit: processor does not support VMX " "operation\n"); return (ENXIO); } /* * Verify that MSR_IA32_FEATURE_CONTROL lock and VMXON enable bits * are set (bits 0 and 2 respectively). */ feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL); if ((feature_control & IA32_FEATURE_CONTROL_LOCK) == 1 && (feature_control & IA32_FEATURE_CONTROL_VMX_EN) == 0) { printf("vmx_modinit: VMX operation disabled by BIOS\n"); return (ENXIO);
dmesgを精査したら、残念なCPUってのが判明しちゃったぞ。
f64 kernel log messages: +avail memory = 998932480 (952 MB) +vmx_modinit: processor does not support VMX operation +module_register_init: MOD_LOAD (vmm, 0xffffffff8213cf90, 0) error 6
research
既に大勢は判明しちゃったけど、後追いしてみる。
FreeBSD 14.0 RELEASE + bhyve で各種 OS を使用する
FreeBSD bhyve hypervisor to run OpenBSD virtual machines
こちらが、判定基準。
Intel CPU
$ egrep '(EPT|UG|VT-x)' /var/run/dmesg.boot VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
AMD CPU
$ grep 'POPCNT' /var/run/dmesg.boot Features2=0x7ed8320b<SSE3,PCLMULQDQ,MON,SSSE3,FMA,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND>
My CPU
CPU: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz (2400.00-MHz K8-class CPU) Origin="GenuineIntel" Id=0x406e3 Family=0x6 Model=0x4e Stepping=3 Features=0xf83fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,SS> Features2=0xfffa3203<SSE3,PCLMULQDQ,SSSE3,FMA,CX16,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND,HV> AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM> AMD Features2=0x121<LAHF,ABM,Prefetch> Structured Extended Features=0x9c27ab<FSGSBASE,TSCADJ,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,NFPUSG,RDSEED,ADX,SMAP,CLFLUSHOPT> Structured Extended Features3=0xbc000400<MD_CLEAR,IBPB,STIBP,L1DFL,ARCH_CAP,SSBD> XSAVE Features=0xf<XSAVEOPT,XSAVEC,XINUSE,XSAVES> IA32_ARCH_CAPS=0x4<RSBA> TSC: P-state invariant Hypervisor: Origin = "VMwareVMware"
こりゃ、駄目だわさ。VMWarePlayerのプロセッサー設定項目に、Intel VT-x/EPT の仮想化ってのが有る。けど、Playerでは有効化しても、無視され る。残念であります。
ChatGPT
そして、恒例のやつ。
Q: FreeBSD/amd64について質問します。manに例として掲載されてたコマンドを 実行すると、エラーになります。考えられる原因と対処方法を詳しく提示して ください。
# bhyveload -m 384M -d ./FreeBSD-14.1-RELEASE-amd64-disc1.iso test-vm bhyveload: vm_create: Device not configured
A: `bhyveload`コマンドを実行するときに発生するエラー「bhyveload:
vm_create
: Device not configured」には、いくつかの原因が考えられます。以下に考えられる原因と対処方法を示します。
### 考えられる原因と対処方法
- VMサポートが有効になっていない
- FreeBSDのbhyveは、カーネルモジュールがロードされている必要があります。`vmm`カーネルモジュールがロードされているか確認してください。
確認方法:
kldstat | grep vmm
結果が空の場合は、モジュールをロードする必要があります。
kldload vmm
永続的に有効にするには、`/boot/loader.conf`に以下の行を追加します。
vmm_load
="YES"
- 適切な権限がない
- `bhyve`はルート権限で実行する必要があります。`root`ユーザーで実行していることを確認してください。
確認方法:
whoami
`root`でない場合は、`sudo`を使ってコマンドを実行します。
sudo bhyveload -m 384M -d ./FreeBSD-14.1-RELEASE-amd64-disc1.iso test-vm
- /dev/vmmが存在しない
- `/dev/vmm`デバイスが存在するか確認してください。
確認方法:
ls /dev/vmm
存在しない場合は、`vmm`カーネルモジュールが正しくロードされていない可能性があります。再度、モジュールのロードを試みてください。
kldload vmm
- VMの設定が正しくない
- VMの名前に問題があるか、既に存在するVMと名前が重複していないか確認してください。
VMの状態を確認するには、`bhyvectl`コマンドを使います。
bhyvectl –vm=test-vm –destroy
- 既存のVMを破棄してから、再度`bhyveload`を実行します。
- bhyveの設定ファイルが不完全
- 設定ファイルやパーミッションに問題がある場合、`bhyveload`が正しく動作しないことがあります。
- `/var/log/messages`などのログファイルを確認し、追加のエラーメッセージや警告がないか確認してください。
### 追加の対処方法
上記の基本的なトラブルシューティングを行った後でも問題が解決しない場合は、以下の追加対策を試みることができます。
- FreeBSDのバージョンを確認
- 使用しているFreeBSDのバージョンが最新であり、すべてのパッケージがアップデートされていることを確認します。
freebsd-version freebsd-update fetch freebsd-update install
- ISOファイルの確認
ISOファイルが正しくダウンロードされており、破損していないことを確認します。
sha256 FreeBSD-14.1-RELEASE-amd64-disc1.iso
- 公式サイトで提供されているチェックサムと一致するか確認してください。
以上の対処方法を試してもエラーが解決しない場合は、より具体的なシステム のログや設定ファイルの内容を確認する必要があります。また、FreeBSDの公 式ドキュメントやフォーラムを参照することも役立ちます。