以下はVMWare Fusion 10.1.1 (macOS High Sierra 10.13.3)で動作確認したものです.
設定ファイル(xxx.vmx)はVM停止中に変更する必要があります(そうでないと書き換わることがある).
コマンドラインツール
/Applications/VMware\ Fusion.app/Contents/Library/ 以下にいくつかコマンドラインツールがインストールされている.
- 起動:
vmrun -T fusion start /path/to/vm.vmx - 停止:
vmrun -T fusion stop /path/to/vm.vmx - 再起動:
vmrun -T fusion reset /path/to/vm.vmx - ディスクのデフラグ:
vmware-vdiskmanager -d disk.vmdk - ディスクのコンパクション:
vmware-vdiskmanager -k disk.vmdk
シリアルポート
設定ファイルに以下を記述
serial0.filename = "/tmp/serial0" serial0.filetype = "pipe" serial0.present = "TRUE"
こうするとゲストVMのCOM1の出力がホストのdomain socket/tmp/serial0へ送られるようになる.
socatを利用して標準出力へ出力できる.
socat -d -d unix-connect:/tmp/serial0 stdio
serial0をserial1に変えればCOM2になる(はず).
Nested Virtualization
設定ファイルに以下を記述
vhv.enable = "TRUE"
あるいは,GUIの方から設定>プロセッサとメモリ>詳細オプションから設定
gdb remote debugging
設定ファイルに以下を記述
debugstub.listen.guest64 = "TRUE" debugstub.port.guest64 = "33333"
こうするとポート33333でgdb serverがlistenするようになる.
VM上でLinuxを実行している場合,以下のようにしてlldbからgdb serverへ接続可能 (vmlinuxは起動しているカーネルイメージ)
% lldb ./vmlinux
(lldb) target create "./vmlinux"
Current executable set to './vmlinux' (x86_64).
(lldb) gdb-remote 33333
Process 1 stopped
* thread #1, stop reason = signal SIGTRAP
frame #0: 0xffffffff818dee06 vmlinux`native_safe_halt at irqflags.h:55
Target 0: (vmlinux) stopped.
(lldb) b sys_close
Breakpoint 2: where = vmlinux`SyS_close + 6 [inlined] SYSC_close at open.c:1153, address = 0xffffffff81265ee6
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, stop reason = breakpoint 2.1
frame #0: 0xffffffff81265ee6 vmlinux`SyS_close at open.c:1155
Target 0: (vmlinux) stopped.
(lldb) disassemble
vmlinux`SyS_close:
0xffffffff81265ee0 <+0>: nopl (%rax,%rax)
0xffffffff81265ee5 <+5>: pushq %rbp
-> 0xffffffff81265ee6 <+6>: movl %edi, %esi
0xffffffff81265ee8 <+8>: movq %gs:0x15bc0, %rax
0xffffffff81265ef1 <+17>: movq 0xac8(%rax), %rax
0xffffffff81265ef8 <+24>: movq %rsp, %rbp
0xffffffff81265efb <+27>: movq %rax, %rdi
0xffffffff81265efe <+30>: callq 0xffffffff8128c7f0 ; __close_fd at file.c:621
0xffffffff81265f03 <+35>: movslq %eax, %rdx
0xffffffff81265f06 <+38>: movq $-0x4, %rax
0xffffffff81265f0d <+45>: leal 0x201(%rdx), %ecx
0xffffffff81265f13 <+51>: cmpl $0x1, %ecx
0xffffffff81265f16 <+54>: jbe 0xffffffff81265f27 ; <+71> at open.c:1153
0xffffffff81265f18 <+56>: movl %edx, %ecx
0xffffffff81265f1a <+58>: andl $-0x3, %ecx
0xffffffff81265f1d <+61>: cmpl $0xfffffdfc, %ecx ; imm = 0xFFFFFDFC
0xffffffff81265f23 <+67>: cmovneq %rdx, %rax
0xffffffff81265f27 <+71>: popq %rbp
0xffffffff81265f28 <+72>: retq
ちなみにLinuxカーネルをデバッグする際はKASLRはオフにしておいた方がいろいろ楽だと思います (ブートプションにnokaslrをつける)
Vagrant
VagrantでVMWare Fusionを利用するには,Vagrant VMWare pluginを購入する必要がある.
Vagrant用Boxの作成
VMWare Fusion用のBoxはあまり作成されていないので,自分で作った方が良いと思います.
基本は適当にVMをセットアップしたのち,VMの保存されているディレクトリへ移動し,
$ vmware-vdiskmanager -d disk.vmdk $ vmware-vdiskmanager -k disk.vmdk $ tar zcvf <box_name>.box *.{nvram,vmsd,vmx,vmxf,vmdk} metadata.json $ vagrant box add <box_name> <box_name>.box --provider vmware_fusion
metadata.jsonの中身は以下の通り
{ "provider": "vmware_fusion" }
VMをセットアップする際の注意点
- vagrantユーザをpassword vagrantで作成する
- ubuntuなら,
adduser vagrant
- ubuntuなら,
- vagrantユーザにパスワード無しでsudoできるように設定
- visudoで
vagrant ALL=(ALL) NOPASSWD: ALL - これをしないと,例えば
vagrant haltしたときにshutdown -h nowの実行に失敗する
- visudoで
- openssh-serverをインストール
- vagrant sshで接続するユーザの
authorized_keysにvagrantの公開鍵を追加- https://github.com/hashicorp/vagrant/blob/master/keys/vagrant.pub
- 初回接続時にvagrantが鍵を自動生成したものに更新する
Vagrantfile
簡単な例
Vagrant.configure("2") do |config| config.vm.box = "ubuntu" config.ssh.guest_port = 22 if ARGV[0] == "ssh" config.ssh.username = "m" else config.ssh.password = "vagrant" end config.vm.provider "vmware_fusion" do |v| v.vmx["memsize"] = 4096 v.vmx["numvcpus"] = 2 v.gui = false end end
vagrant sshしたときはvagrant以外のユーザに接続したいので,ARGV[0]の値に応じて,vagrant sshならuser mで接続,そうでない場合はuser vagrantで接続するように設定している.
(user vagrantで接続する際はパスワード認証)
VMWare設定ファイル
VMWareの設定ファイルは .vagrant/machines/default/vmware_fusion/xxxxxxx/以下に存在
VMWare Fusionライブラリでの表示
VagrantでheadlessでVMを起動している場合,VMWare Fusionのライブラリの方にVMの情報が出てこない (https://github.com/hashicorp/vagrant/issues/8466)
少し試行錯誤したところ,どうやら一旦v.gui=trueで起動すればライブラリの方へ追加されるようである.