VMware vSphere 6のVMDirectPath I/OデバイスがPowerCLIでVMに追加できない

この記事は、[「クラウド時代のシステム管理」の記事](http://www.takanyan.net/vmdirectpathio-cli/)を転記したものです。

VMware vSphereにはPCI接続のデバイスを直接仮想マシンに認識させることができる「VMDirectPath I/O」という機能があります。この機能を使うと、仮想化のオーバーヘッドを極力減らした状態で物理デバイスを利用できます。今回、VMDirectPath I/Oをコマンドラインでうまく認識させることが出来なかったので、調べた情報などをまとめておきたいと思います。

<more>

## 1. VMDirectPath I/Oでデバイスを利用するための事前設定

まずはVMDirectPath I/Oの動作確認をするための環境を用意します。今回は以下のような環境で検証を行いました。

|項目|値|
|---|---|
| 機種 | Fujitsu Primergy TX100 S3P |
| CPU | Xeon E3 1225 (4Core/4Thread) |
| BIOS | VT-dを有効化 |
| Hypervisor | VMware ESXi 6.0 Update2 (build 3620759) |
| PCIデバイス | Intel SSD 910 400GB |

VMDirectPath I/Oの設定はvSphere Clientでの「構成」＞ハードウェア枠内の「詳細設定」から行うことが出来ます。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-setup01.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-setup01.png" alt="VMDirectPathIO初期設定画面" width="980" height="659" class="aligncenter size-full wp-image-207" /></a>

詳細設定画面の右上にある「編集」をクリックするとVMDirectPath I/Oで利用する対象デバイスを選択できます。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-setup02.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-setup02.png" alt="VMDirectPathIO対象デバイスの選択画面" width="649" height="477" class="aligncenter size-full wp-image-208" /></a>

ここではIntel SSD 910にチェックをつけてOKボタンをクリックします。設定はホストの再起動後に反映されます。以上で、VMDirectPath I/Oでデバイスを利用するための事前準備が完了します。
 
## 2. vSphere Clientを利用した仮想マシンへのPCIデバイスの接続

### 2-1. 前提条件

vSphere ClientやWeb ClientなどのGUI経由ではVMDirectPath I/Oの設定は簡単に実行でき、正常に完了します。なお、仮想マシンへのPCIデバイスの追加には以下の条件を満たす室用があります。

* 仮想マシンが停止状態であること
* 仮想マシンの予約メモリ容量が上限メモリ容量と一致していること（「すべてのメモリ領域を予約」にチェックをつける必要はない）
* BIOSモードの仮想マシンで1VMあたりの接続可能PCIデバイスの数はPCI BARサイズの合計が1GBまで
* uEFIモードの仮想マシンで1VMあたりの接続可能PCIデバイスの数はPCI BARサイズの合計が32GBまで
* 1ESXiホストあたり利用可能なPCIデバイスの数はPCI BARサイズの合計32GBまでに制限される

ここで出てきた「PCI BARサイズ」とは、PCIデバイスがそれぞれ持っているアドレス空間のサイズです。なおPCI BARには5つの領域があり、上記のBARサイズは5つの領域の合計容量です。BARサイズはLinux OSでは<code>lspci</code>コマンドで、ESXiではシェルログインしたうえで<code>esxcfg-info</code>で確認可能です。

```Shell
# esxcfg-info | less
(省略)
            \==+PCI Device :
(省略)
               |----Device Id.......................................0x0072
               |----Sub-Vendor Id...................................0x8086
               |----Sub-Device Id...................................0x3700
               |----Vendor Name.....................................LSI Logic / Symbios Logic
               |----Device Name.....................................Intel(R) SSD 910 Series
(省略)
               \==+BAR Info :
                  \==+BAR0 :
                     |----Type......................................0x00000001
                     |----Address...................................0x000000000000e000
                     |----Size......................................256
                     |----Flags.....................................0x00000001
                  \==+BAR1 :
                     |----Type......................................0x00000003
                     |----Address...................................0x00000000f7dc0000
                     |----Size......................................16384
                     |----Flags.....................................0x00000004
                  \==+BAR2 :
                     |----Type......................................0x00000004
                     |----Address...................................0
                     |----Size......................................0
                     |----Flags.....................................0
                  \==+BAR3 :
                     |----Type......................................0x00000003
                     |----Address...................................0x00000000f7d80000
                     |----Size......................................262144
                     |----Flags.....................................0x00000004
                  \==+BAR4 :
                     |----Type......................................0x00000004
                     |----Address...................................0
                     |----Size......................................0
                     |----Flags.....................................0
                  \==+BAR5 :
                     |----Type......................................0
                     |----Address...................................0
                     |----Size......................................0
                     |----Flags.....................................0
(省略)
```

### 2-2. 仮想マシンへのPCIデバイスの接続（vSphere Client）

あらかじめ何らかの仮想マシンが作成されている前提で以下の説明を進めます。まず、仮想マシンの「設定の編集」を開始します。設定画面で「追加」ボタンをクリックします。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig01.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig01.png" alt="VMDirectPathIO 仮想マシンへのPCIデバイス追加開始" width="694" height="625" class="aligncenter size-full wp-image-209" /></a>

次に追加するデバイスとして「PCIデバイス」を選択します。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig02.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig02.png" alt="VMDirectPathIOのPCIデバイス選択" width="638" height="509" class="aligncenter size-full wp-image-212" /></a>

プルダウンリストにあらかじめ設定していたデバイスが表示されるので、接続したいデバイスを選択して次へ進みます。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig03.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig03.png" alt="VMDirectPathIOの実デバイス選択" width="638" height="509" class="aligncenter size-full wp-image-213" /></a>

設定内容を確認して「終了」ボタン句をクリックします。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig04.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig04.png" alt="VMDirectPathIOの接続対象デバイスの確認" width="638" height="509" class="aligncenter size-full wp-image-210" /></a>

仮想マシンの設定自体も完了させて、PCIデバイスの接続を確認します。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig05.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-vmconfig05.png" alt="VMDirectPathIOの仮想マシン接続設定の完了" width="694" height="625" class="aligncenter size-full wp-image-211" /></a>


仮想マシンを起動する前に、メモリの割り当てと予約が同じ値になっていることをリソース設定から確認します。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-memory.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/directpathio-memory.png" alt="VMDrectPathIO設定をしたメモリ予約の確認" width="694" height="625" class="aligncenter size-full wp-image-214" /></a>

メモリの予約の値が割り当てと一致していることを確認したら、仮想マシンを起動します。起動が完了したら、デバイスが認識されていることを確認します。

```Shell
[root@localhost ~]# lsscsi
[0:0:0:0]    disk    VMware   Virtual disk     1.0   /dev/sda
[0:0:1:0]    disk    VMware   Virtual disk     1.0   /dev/sdb
[1:0:0:0]    disk    INTEL(R)  SSD 910 200GB   a424  /dev/sdc
[1:0:1:0]    disk    INTEL(R)  SSD 910 200GB   a424  /dev/sdd
[2:0:0:0]    cd/dvd  NECVMWar VMware IDE CDR00 1.00  /dev/sr0
```

以上でGUIからはVMDirectPath I/Oの設定が成功しました。

## 3. PowerCLIからのVMDirectPath I/Oの設定

VMwareの操作を行うコマンドラインツールにはいくつかの種類がありますが、今回取り上げるのはPowerCLIです。PowerCLIはPowerShellでVMware ESXiの操作ができるため、Windows版のvCenter Serverと相性が良く、私はよく業務で使っています。しかし、VMDirectPath I/Oの設定ではバグにより設定がうまくいきませんでした。

### 3-1. PowerCLIによるVMDirectPath I/Oの設定方法

仮想マシンにPCIデバイスを接続するためには、対象VMとデバイスのオブジェクトを作成し、<code>Add-PassthroughDevice</code>コマンドレットで接続設定を行います。
 
<pre class="lang:ps decode:true " >PowerCLI C:\> Connect-VIServer (ESXiホスト名)
PowerCLI C:\> $VM = Get-VM (VM名)
PowerCLI C:\> $PCIDEVICE = Get-PassthroughDevice -VMHost (ESXiホスト名) -Name "(デバイス名)"
PowerCLI C:\> Add-PassthroughDevice -VM $VM -PassthroughDevice $PCIDEVICE

Key        Name                           VendorName                     Type
---        ----                           ----------                     ----
13000      Intel(R) SSD 910 Series        LSI Logic / Symbios Logic      Pci</pre> 

設定反映後に仮想マシンの電源を入れると以下のようなエラーが出て起動に失敗してしまいます。

<a href="http://www.takanyan.net/wp-content/uploads/2016/08/start-error.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/08/start-error.png" alt="VMDirectPathIOをPoserCLIで設定した後のVM起動時エラー" width="620" height="353" class="aligncenter size-full wp-image-218" /></a>

### 3-2. 起動失敗の原因

原因はPowerCLIでPCIデバイスを設定する際に、「DeviceID」を間違って設定していることにあります。2-1.節で書いていた<code>esxcfg-info</code>の結果によると、今回のPCIデバイスの「Device ID」は<strong>0x0072</strong>となります。この設定は仮想マシンのVMXファイルにも記述されます。しかし、PowerCLIで設定を行うと以下のようにPCIデバイスのDevice IDが間違った値で設定されてしまいます。

```Shell
### GUIで設定した場合 ###
# grep pciPassthru0.deviceId (vmxファイル)
pciPassthru0.deviceId = "0x0072"

### PowerCLIで設定した場合 ###
# grep pciPassthru0.deviceId (vmxファイル)
pciPassthru0.deviceId = "0x0114"
```

これは、PowerCLIでPCIデバイスの情報を仮想マシンに追加する際にDevice IDを10進数から16進数に修正しないで設定変更リクエストを行っているためと思われます。0x72=114だからです。

## 4. 参考文献など

VMDirectPath I/Oの制限事項や今回の不具合に関する情報は、以下のようなコミュニティのやり取りに記述があります。PowerCLI 4.0のころからずっとこのままのようですので、そろそろ直してほしいものです。

* <a href="https://kb.vmware.com/kb/2078748" target="_blank">VMware ESX/ESXi ホスト上の VMDirectPath I/O パススルー デバイスの構成 (2078748)</a>
* <a href="https://kb.vmware.com/kb/2144754" target="_blank">VMware vSphere VMDirectPath I/O：プラットフォームとデバイスの要件 (2144754)</a>
* <a href="http://ravatheodor.blogspot.jp/2013/01/vmware-directpath-io-adding-pasthrough.html" target="_blank">VMware DirectPath I/O - adding passthrough PCI devices to VM</a>

さて、どうしたものかな・・・・・・