13.7. Using an NPIV Virtual Adapter (vHBA) with SCSI Devices
NPIV (N_Port ID Virtualization) is a software technology that allows sharing of a single physical Fibre Channel host bus adapter (HBA).
This allows multiple guests to see the same storage from multiple physical hosts, and thus allows for easier migration paths for the storage. As a result, there is no need for the migration to create or copy storage, as long as the correct storage path is specified.
In virtualization, the virtual host bus adapter, or vHBA, controls the LUNs for virtual machines. For a host to share one Fibre Channel device path between multiple KVM guests, a vHBA must be created for each virtual machine. A single vHBA must not be used by multiple KVM guests.
Each vHBA for NPIV is identified by its parent HBA and its own World Wide Node Name (WWNN) and World Wide Port Name (WWPN). The path to the storage is determined by the WWNN and WWPN values. The parent HBA can be defined as
scsi_host# or as a WWNN/WWPN pair.
Note
If a parent HBA is defined as
scsi_host# and hardware is added to the host machine, the scsi_host# assignment may change. Therefore, it is recommended that you define a parent HBA using a WWNN/WWPN pair.
This section provides instructions for configuring a vHBA persistently on a virtual machine.
Note
Before creating a vHBA, it is recommended to configure storage array (SAN)-side zoning in the host LUN to provide isolation between guests and prevent the possibility of data corruption.
13.7.1. Creating a vHBA
Procedure 13.8. Creating a vHBA
Locate HBAs on the host system
To locate the HBAs on your host system, use thevirsh nodedev-list --cap vportscommand.For example, the following output shows a host that has two HBAs that support vHBA:#
virsh nodedev-list --cap vportsscsi_host3 scsi_host4-
Check the HBA's details
Use thevirsh nodedev-dumpxml HBA_devicecommand to see the HBA's details.The XML output from thevirsh nodedev-dumpxmlcommand will list the fields<name>,<wwnn>, and<wwpn>, which are used to create a vHBA. The<max_vports>value shows the maximum number of supported vHBAs.# virsh nodedev-dumpxml scsi_host3 <device> <name>scsi_host3</name> <path>/sys/devices/pci0000:00/0000:00:04.0/0000:10:00.0/host3</path> <parent>pci_0000_10_00_0</parent> <capability type='scsi_host'> <host>3</host> <unique_id>0</unique_id> <capability type='fc_host'> <wwnn>20000000c9848140</wwnn> <wwpn>10000000c9848140</wwpn> <fabric_wwn>2002000573de9a81</fabric_wwn> </capability> <capability type='vport_ops'> <max_vports>127</max_vports> <vports>0</vports> </capability> </capability> </device>In this example, the<max_vports>value shows there are a total 127 virtual ports available for use in the HBA configuration. The<vports>value shows the number of virtual ports currently being used. These values update after creating a vHBA. Create a vHBA host device
Create an XML file similar to one of the following for the vHBA host. In this examples, the file is named vhba_host3.xml.This example usesscsi_host#to describe the parent vHBA.# cat vhba_host3.xml <device> <parent>scsi_host3</parent> <capability type='scsi_host'> <capability type='fc_host'> </capability> </capability> </device>This example uses a WWNN/WWPN pair to describe the parent vHBA.# cat vhba_host3.xml <device> <name>vhba</name> <parent wwnn='20000000c9848140' wwpn='10000000c9848140'/> <capability type='scsi_host'> <capability type='fc_host'> </capability> </capability> </device>Note
The WWNN and WWPN values must match those in the HBA details seen in Step 2.The<parent>field specifies the HBA device to associate with this vHBA device. The details in the<device>tag are used in the next step to create a new vHBA device for the host. For more information on thenodedevXML format, see the libvirt upstream pages.Create a new vHBA on the vHBA host device
To create a vHBA on vhba_host3, use thevirsh nodedev-createcommand:#
virsh nodedev-create vhba_host3.xmlNode device scsi_host5 created from vhba_host3.xmlVerify the vHBA
Verify the new vHBA's details (scsi_host5) with thevirsh nodedev-dumpxmlcommand:# virsh nodedev-dumpxml scsi_host5 <device> <name>scsi_host5</name> <path>/sys/devices/pci0000:00/0000:00:04.0/0000:10:00.0/host3/vport-3:0-0/host5</path> <parent>scsi_host3</parent> <capability type='scsi_host'> <host>5</host> <unique_id>2</unique_id> <capability type='fc_host'> <wwnn>5001a4a93526d0a1</wwnn> <wwpn>5001a4ace3ee047d</wwpn> <fabric_wwn>2002000573de9a81</fabric_wwn> </capability> </capability> </device>
13.7.2. Creating a Storage Pool Using the vHBA
It is recommended to define a libvirt storage pool based on the vHBA in order to preserve the vHBA configuration.
Using a storage pool has two primary advantages:
- the libvirt code can easily find the LUN's path via virsh command output, and
- virtual machine migration requires only defining and starting a storage pool with the same vHBA name on the target machine. To do this, the vHBA LUN, libvirt storage pool and volume name must be specified in the virtual machine's XML configuration. Refer to Section 13.7.3, “Configuring the Virtual Machine to Use a vHBA LUN” for an example.
Create a SCSI storage pool
To create a persistent vHBA configuration, first create a libvirt'scsi'storage pool XML file using the format below. When creating a single vHBA that uses a storage pool on the same physical HBA, it is recommended to use a stable location for the<path>value, such as one of the/dev/disk/by-{path|id|uuid|label}locations on your system.When creating multiple vHBAs that use storage pools on the same physical HBA, the value of the<path>field must be only/dev/, otherwise storage pool volumes are visible only to one of the vHBAs, and devices from the host cannot be exposed to multiple guests with the NPIV configuration.More information on<path>and the elements within<target>can be found at http://libvirt.org/formatstorage.html.Example 13.3. Sample SCSI storage pool SML syntax
In the following example, the'scsi'storage pool is named vhbapool_host3.xml:<pool type='scsi'> <name>vhbapool_host3</name> <source> <adapter type='fc_host' wwnn='5001a4a93526d0a1' wwpn='5001a4ace3ee047d'/> </source> <target> <path>/dev/disk/by-path</path> <permissions> <mode>0700</mode> <owner>0</owner> <group>0</group> </permissions> </target> </pool>Alternatively, the following syntax is used when vhbapool_host3.xml is one of more vHBA storage pools on a single HBA:<pool type='scsi'> <name>vhbapool_host3</name> <source> <adapter type='fc_host' wwnn='5001a4a93526d0a1' wwpn='5001a4ace3ee047d'/> </source> <target> <path>/dev/</path> <permissions> <mode>0700</mode> <owner>0</owner> <group>0</group> </permissions> </target> </pool>Important
In both cases, the pool must betype='scsi'and the source adapter type must be'fc_host'. For a persistent configuration across host reboots, thewwnnandwwpnattributes must be the values assigned to the vHBA (scsi_host5 in this example) by libvirt.Optionally, the'parent'attribute can be used in the<adapter>field to identify the parent scsi_host device as the vHBA. Note, the value is not the scsi_host of the vHBA created byvirsh nodedev-create, but it is the parent of that vHBA.Providing the'parent'attribute is also useful for duplicate pool definition checks. This is more important in environments where both the'fc_host'and'scsi_host'source adapter pools are being used, to ensure a new definition does not duplicate using the same scsi_host of another existing storage pool.The following example shows the optional'parent'attribute used in the<adapter>field in a storage pool configuration:<adapter type='fc_host' parent='scsi_host3' wwnn='5001a4a93526d0a1' wwpn='5001a4ace3ee047d'/>
Define the pool
To define the storage pool (named vhbapool_host3 in this example) persistently, use thevirsh pool-definecommand:#
virsh pool-define vhbapool_host3.xmlPool vhbapool_host3 defined from vhbapool_host3.xmlStart the pool
Start the storage pool with the following command:#
virsh pool-start vhbapool_host3Pool vhbapool_host3 startedNote
When starting the pool,libvirtwill check if a vHBA with the samewwpn:wwnnidentifier already exists. If it does not yet exist, a new vHBA with the providedwwpn:wwnnwill be created. Correspondingly, when destroying the pool, libvirt will destroy the vHBA that uses the samewwpn:wwnnvalues as well.Enable autostart
Finally, to ensure that subsequent host reboots will automatically define vHBAs for use in virtual machines, set the storage pool autostart feature (in this example, for a pool named vhbapool_host3):#
virsh pool-autostart vhbapool_host3
13.7.3. Configuring the Virtual Machine to Use a vHBA LUN
After a storage pool is created for a vHBA, add the vHBA LUN to the virtual machine configuration by creating a disk volume on the virtual machine in the virtual machine's XML. Specify the storage
pool and the volume in the <source> parameter, using the following as an example:
<disk type='volume' device='disk'>
<driver name='qemu' type='raw'/>
<source pool='vhbapool_host3' volume='unit:0:4:0'/>
<target dev='hda' bus='ide'/>
</disk>
To specify a
lun device instead of a disk, refer to the following example:
<disk type='volume' device='lun' sgio='unfiltered'>
<driver name='qemu' type='raw'/>
<source pool='vhbapool_host3' volume='unit:0:4:0' mode='host'/>
<target dev='sda' bus='scsi'/>
<shareable />
</disk>
For XML configuration examples of adding SCSI LUN-based storage to a guest, see Section 14.5.3, “Adding SCSI LUN-based Storage to a Guest”.
Note that to ensure successful reconnection to a LUN in case of a hardware failure, it is recommended to edit the
fast_io_fail_tmo and dev_loss_tmo options. For more information, see Reconnecting to an exposed LUN after a hardware failure.
13.7.4. Destroying the vHBA Storage Pool
A vHBA created by the storage pool can be destroyed by the
virsh pool-destroy command:
# virsh pool-destroy vhbapool_host3
Note that executing the
virsh pool-destroy command will also remove the vHBA that was created in Section 13.7.1, “Creating a vHBA”.
To verify the pool and vHBA have been destroyed, run:
# virsh nodedev-list --cap scsi_host
scsi_host5 will no longer appear in the list of results.