初始化
nova要求用户指定计算节点上可以直通的设备白名单(以设备的vendor id和product id为标志)。nova-compute在启动阶段从配置文件中读取用户配置的白名单,并且通过libvirt接口查询到所有的设备列表。分别保存在内存和数据库中。
resource tracker
中增加pci_tracker
。pci_tracker
的数据结构如下。数据库中保存pci_devices
和compute_nodes
两张表。
compute_nodes
中记录计算节点上可用设备的类型和数量(pci_stats的内容)
pci_stats格式:
[{"count": 32, "vendor_id": "8086", "product_id": "10ed", "extra_info": {}}]
pci_devices
记录每一个可用PCI设备信息和当前状态。
pci设备状态:
aviliable 可用
claimed 已被预占
allocated 已被占用
虚拟机创建 计算节点收到带有pci设备的调度请求后,为当前请求预留并占用对应的pci设备,更新到resource_tracker
的PciDeviceList
。并且记录到claims
和allocations
中。
生成xml文件时,检查system metadata中是否存在pci设备请求,如果存在,则生成对应的hostdev
配置项。
虚拟机删除 虚拟机删除时,更新计算节点resource_tracker
的PciDeviceList
和allocations
。并且更新节点的pci_stats
。
配置文件中指定alias别名:
pci_alias = { "vendor_id":"8086", "product_id":"10ed", "dev_type":"type-VF", "name":"82599" }
flavor中指定使用某个别名的设备及数量
+----------------------------+--------------------------------------+
| Property | Value |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| disk | 20 |
| extra_specs | {"pci_passthrough:alias": "82599:1"} |
| id | 8086001 |
| name | flavor_sriov_8g20g4u |
| os-flavor-access:is_public | True |
| ram | 8192 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 4 |
+----------------------------+--------------------------------------+
调度器:
Havana版本提供了PciPassthroughFilter
的调度器,调度策略为如果instance的system_metadata中包含直通pci设备的请求,则检查计算节点的pci_stats
是否满足PCI设备的需求。如果满足则通过过滤,否则过滤失败。
节点选定之后,会从选定节点的pci_stats
中移除相应类型和数量的pci设备,防止并发调度失败。
pci_tracker
初始化阶段,不会从数据库读取原有的设备信息,直接扫描宿主机节点之后重写数据库。导致原有已分配的设备变为可用状态。修改为在初始化时先读取数据库。dev_type
字段,否则在调度时无法判断设备类型新的pci_stats内容如下:
[{"dev_type": "type-VF", "count": 1, "vendor_id": "8086", "product_id": "10ed", "extra_info": {"vlan_tag": 2, "dpdk-trunk": "0000:01:10.2", "phys_function": [["0x0000", "0x01", "0x00", "0x0"]]}}]
<interface type='hostdev' managed='yes'>
<mac address='fa:16:3e:4e:d6:32'/>
<driver name='vfio'/>
<source>
<address type='pci' domain='0x0000' bus='0x01' slot='0x11' function='0x7'/>
</source>
<vlan>
<tag id='3011'/>
</vlan>
<alias name='hostdev0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</interface>
绑定:
ovs-vsctl set Interface dpdk-trunk-0000.01.10.2 external_ids:vlan-3012=b2177122-69e0-4076-9618-4303c834213b
解绑:
ovs-vsctl remove Interface dpdk-trunk-0000.01.10.2 external_ids:vlan-3012=b2177122-69e0-4076-9618-4303c834213b
nova api中的检查
目标节点compute prep_resize
检查节点合法性
本节点资源预留
如果禁用resource tracker,则仅生成一个migration对象
申请资源
生成一个migration对象
extrac新flavor的信息到instance system metadata中,带有"new_"前缀。
检查instance system metadata中如果包含pci设备请求,在当前节点的pci_dev_list里面申请符合条件的pci设备,并且添加到claims中。
更新节点资源信息到数据库
调用源节点resize_instance
源节点resize_instance
目标节点finish_resize
old_
前缀 原有带new_
前缀的instance system metadata去掉前缀,instance属性值变为resize目的flavor的属性值。目标节点confirm resize
源节点confirm_resize
old_
前缀的属性值虚拟机状态刷新
_instance_update(目的端操作)
当虚拟机状态修改之后需要通过这个方法更新云主机的数据库记录。
定时任务刷新(源端和目的端都存在)
update_pci_info_for_instance
vm_state DELETED
清理allocations和claims
task_state RESIZE_MIGRATED
清理源端allocations
task_state RESIZE_FINISH
claims->allocations
claims和allocations中都没有pci设备
根据instance中的pci_requests内容重新获取一次pci设备,更新pci_tracker中的pci_devs_list,claims,allocations
update_pci_for_migration
云主机状态为RESIZED或者task_state为RESIZE_PREP,RESIZE_MIGRATING,RESIZE_MIGRATED,RESIZE_FINISH的状态
从system metadata中获取prefix为new_的配置,并且claim这些设备
Havana版本其实只实现了简单的pci设备管理功能,对虚拟机的resize操作没有支持,因此在上面的resize流程中可以看到全程没有主动管理pci设备的状态。 主要存在问题如下:
本文来自网易实践者社区,经作者岳文远授权发布。