前言

Clear Linux 是针对 Intel 平台的滚动 Linux 发行版。它有很多优势,我个人目前主要用来针对老机型(四代酷睿平台)的裸机运行平台,并主要用来跑虚拟机。

由于 Clear Linux 是过于强调精简的发行版,因此配置方面需要额外的精力,所在这里针对 KVM 虚拟机的配置做个记录。

BIOS 配置

针对硬件直通这块,首先需要 CPU 的支持,四代平台支持 VT-D 功能的不多,主要集中在 i5、i7 的 CPU。个人购买过四代 i3 的 CPU 发现并不支持硬件直通,所以又退款换货非常的折腾。

了解了支持的 CPU 以后,然后在 BIOS 中对应的开启虚拟化以及 VT-D,这里就不表。

内核配置

和其他的发行版不同,Clear Linux 的引导器是 Intel 自己研发的 clr-boot-manager。内核的参数文件具体的文件路径在 /etc/kernel/cmdline.d/ 这个目录中,然后对应的示例文件 iommu.conf:

intel_iommu=on iommu=pt vfio_iommu_type1.allow_unsafe_interrupts=1 vfio-pci.ids=<id>,<id>

这个 ID 是 PCI ID,对应的可以使用 lspci -nn 获得,例如列出网卡的 PCI ID:

$ lspci -nn | grep -i Ether
00:19.0 Ethernet controller [0200]: Intel Corporation Ethernet Connection I217-V [8086:153b] (rev 04)
02:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533] (rev 03)

同时,需要注意的是 IOMMU Group 分组是否在一个组中(这个可能需要 PCI 设备的支持),可以使用以下简单的 Shell 脚本查看(来自 Arch 的 Wiki):

#!/bin/bash
shopt -s nullglob
for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;

然后,使用 clr-boot-manager update 生成启动配置,然后 reboot 重启后查看 cat /proc/cmdline 内核引导参数是否已经生效。

Qemu 配置

查看 Qemu 下 PCI 的设备列表,例如

$  virsh nodedev-list | grep pci
pci_0000_00_00_0
pci_0000_00_02_0
pci_0000_00_03_0
pci_0000_00_14_0
pci_0000_00_16_0
pci_0000_00_19_0
pci_0000_00_1a_0
pci_0000_00_1c_0
pci_0000_00_1c_3
pci_0000_00_1d_0
pci_0000_00_1f_0
pci_0000_00_1f_2
pci_0000_00_1f_3
pci_0000_02_00_0

那么根据对并上面

$ lspci -nn | grep -i Ether
00:19.0 Ethernet controller [0200]: Intel Corporation Ethernet Connection I217-V [8086:153b] (rev 04)
02:00.0 Ethernet controller [0200]: Intel Corporation I210 Gigabit Network Connection [8086:1533] (rev 03)

两块网卡的 ID 分别为 pci_0000_00_19_0 和 pci_0000_02_00_0 ,然后我们 dump 出配置来

$ virsh nodedev-dumpxml pci_0000_00_19_0
<device>
  <name>pci_0000_00_19_0</name>
  <path>/sys/devices/pci0000:00/0000:00:19.0</path>
  <parent>computer</parent>
  <driver>
    <name>vfio-pci</name>
  </driver>
  <capability type='pci'>
    <class>0x020000</class>
    <domain>0</domain>
    <bus>0</bus>
    <slot>25</slot>
    <function>0</function>
    <product id='0x153b'>Ethernet Connection I217-V</product>
    <vendor id='0x8086'>Intel Corporation</vendor>
    <iommuGroup number='4'>
      <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
    </iommuGroup>
  </capability>
</device>

例如以上就可以 dump 出具体 PCI 信息的来,可以比较直观的看到 product id 以及生产商 vendor id 等信息。这里需要的几个参数分别是 domainbusslot、以及 function

我们分别记录下来,然后填写到以下的 xml 片段中,例如上面对应的数值就是

<hostdev mode='subsystem' type='pci' managed='yes'>
  <driver name='vfio'/>
  <source>
    <address domain='0' bus='0' slot='25' function='0'/>
  </source>
</hostdev>

可以直接使用十进制数值,因为 virsh edit 在编辑保存的时候会自动计算其原始的十六进制数值。

验证

使用 virsh edit 编辑对应的虚拟机配置,例如 virsh edit <my-machine> 。在编辑器中将上述 的 xml 粘贴入 devices 这个 xml 块中,保存关机然后在启动虚拟机即可生效。

在启动虚拟机以后,例如上述的网卡直通可以使用 ip a 等命令查看虚拟机有无识别到对应的物理网卡。如果一切顺利,那么就可以使用对应的网络配置程序来配置对应网卡的网络信息,这里不在复述。

常见问题

  1. 查看 IOMMU Group 中的设备是否分别在不同的组中,如果多个设备在同个组中,则需要额外的操作(参见 Arch Wiki 的内容);
  2. 如果物理机设备被直通出去,那么就无法使用该设备以及设备树下的子设备。例如,如果直通 USB 控制器给虚拟机,那么这个控制器下的键盘、鼠标都只能在虚拟机下使用;
  3. 直通的内核模块应该优先于其对应的物理设备驱动,否则会造成冲突造成无法直通,因此可以考虑搭配内核 blacklist 使用。

最后,如果服务器是 Intel 平台的,强烈建议尝试下 Clear Linux 你会爱上它的!

参考信息