The following document illustrates an API for host device enumeration,
creation and deletion. This has a number of use cases:
- PCI passthrough. Need to enumerate PCI devices, get their domain,
bus, slot, function IDs to be able to pass-though to a guest.
Need to disable the host kernel driver. Need to get metadata about
the device to present to the user, eg model / vendor.
- USB passthrough. Need to enumerate USB devices, get their bus, device
IDs to be able to pass-though to a guest. Need to disable the host
kernel driver. Need to get metadata about the device to present to
the user, eg model / vendor.
- Fibre Channel. Need to enumerate SCSI HBAs with FC capability and
get their WWNN and WWPN (World Wide Node/Port Name) to enable the
administrator to associate with the SAN.
This relates to the SCSI storage pool impl I posted last week
- NPIV. Need to create/delete NPIV virtual Fibre Channel adapters.
This relates to the SCSI storage pool impl I posted last week
- Networking. Need to enumerate NICs, bridges, VLANs, bonding.
This all sounds like alot of data / stuff to manage, but the good news
is that there is already an application which does most of this for
us. ie HAL. So at the basic level all we need to do is map the HAL
properties into a libvirt XML format for describing devices.
I have chosen to define a very direct mapping.
- At the top level, "<device>" element
- A short 'name' and longer 'key' both unique to host
The key is the HAL 'udi' value
- A 'parent' key to show nesting of devices.
- Optional 'bus' information inside a <bus> element
Bus names will map straight into HAL bus names.
The content is bus specific
- Optional 'capability' information inside one or more
<capability> elements. NB a single device can provide
several capabilites. Capability names will map straight
onto HAL capability names. The content is capability
specific.
- Capabilities can be nested for specialization. eg a
'net' capability can have a '80211' sub-capability
if it is a wifi device.
Now some example XML descriptions....
An arbitrary PCI device
<device>
<name>pci_8086_27c5</name>
<key>/org/freedesktop/Hal/devices/pci_8086_27c5</key>
<parent>/org/freedesktop/Hal/devices/computer</parent>
<bus type="pci">
<vendor id="32902">Intel Corporation</vendor>
<product id="10202">82801G (ICH7 Family) SMBus
Controller</product>
<address domain="0000" bus="00" slot="1f"
function="3"/>
</bus>
</device>
An arbitrary USB device
<device>
<name>usb_device_483_2016_noserial</name>
<key>/org/freedesktop/Hal/devices/usb_device_483_2016_noserial</key>
<parent>/org/freedesktop/Hal/devices/usb_device_0_0_0000_00_1d_3</parent>
<bus type="usb">
<vendor id="1155">SGS Thomson Microelectronics</vendor>
<product id="8214">Fingerprint Reader</product>
<address bus="003" dev="005"/>
</bus>
</device>
A SCSI HBA
<device>
<name>pci_8086_27df_scsi_host</name>
<key>/org/freedesktop/Hal/devices/pci_8086_27df_scsi_host</key>
<parent>/org/freedesktop/Hal/devices/pci_8086_27df</parent>
<capability type="scsihost">
<capability type="fc">
<address wwnn="023432532532632" wwpn="32453253252352"/>
<vports max="4"/>
</capability>
</capability>
</device>
As an example, consider a wireless NIC
<device>
<name>net_00_13_02_b9_f9_d3_0</name>
<key>/org/freedesktop/Hal/devices/net_00_13_02_b9_f9_d3_0</key>
<parent>/org/freedesktop/Hal/devices/pci_8086_4227</parent>
<capability type="net">
<hwaddr>00:13:02:b9:f9:d3</hwaddr>
<name>eth0</name>
<capability type="80211"/>
</capability>
</device>
Notice how the specific functional devices like NICs, HBAs, are
children of the physical USB or PCI device. This is where the
hierarchy comes in.
There are a few other types of devices we want explicit representations
for, block devices, sound devices, storage devices, input devices. I
want describe them here, but they follow same pattern of mapping the
XML onto the HAL properties in their <capability> tags.
There are some devices HAL does not represent so we'll have to augment
the HAL information. Specifically devices which don't correspond to
a physical device, eg
- Bonding NICs
- Bridges
- VLANs
There are also cases where HAL does not have enough properties so we
again need to augment the data
- Fibre Channel / NPIV: Add WWPN, WWNN
The API to deal with this is really very simple. APIs to query all
devices, or query devices based on a capability, or bus type:
int
virNodeNumOfDevices(virConnectPtr conn)
int
virNodeListDevices(virConnectPtr conn,
char **const names,
int maxnames)
int
virNodeNumOfDevicesByCap(virConnectPtr conn,
const char *cap)
int
virNodeListDevicesByCap(virConnectPtr conn,
const char *cap,
char **const names,
int maxnames)
int
virNodeNumOfDevicesByBus(virConnectPtr conn,
const char *bus)
int
virNodeListDevicesByBus(virConnectPtr conn,
const char *bus,
char **const names,
int maxnames)
Then APIs to obtain a virNodeDevicePtr object corresponding to a
device name / key :
virNodeDevicePtr
virNodeDeviceLookupByName(virConnectPtr conn, const char *name)
virNodeDevicePtr
virNodeDeviceLookupByName(virConnectPtr conn, const char *key)
int
virNodeDeviceFree(virNodeDevicePtr dev)
An API to get the XML description:
char *
virNodeDeviceDumpXML(virConnectPtr conn,
unsigned int flags)
Finally an API to create / delete devices - this is only for devices
with certain capabilities
virNodeDevicePtr
virNodeDeviceCreate(virConnectPtr conn,
const char *xml)
int
virNodeDeviceDestroy(virNodeDevicePtr dev)
BTW if you want to see all the HAL metadata on your machine run
lshal
I don't propose to expose all the data - only specific properties we have
immediate need for. The HAL spec describes the meaning of various props
http://people.freedesktop.org/~david/hal-spec/hal-spec.html
Dan.
--
|: Red Hat, Engineering, Boston -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|