VMWare Fusionメモ

以下は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

VagrantVMWare 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をセットアップする際の注意点

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で起動すればライブラリの方へ追加されるようである.

その他

  • ディスクサイズの変更は面倒なようなので,あらかじめ余裕を持ってディスクを作成しておくのが吉
  • 起動中のVMからboxを作成するvagrant packgeコマンドはVMWareでは使えない