设备管理:device_manager.rs
概述
device_manager.rs 是虚拟机设备管理的核心模块,负责所有设备的创建、配置、挂载和生命周期管理。本文深入分析其设计和实现。
核心结构
DeviceManager
rust
// vmm/src/device_manager.rs (5036 行)
pub struct DeviceManager {
// 设备列表
devices: Vec<Arc<Mutex<dyn PciDevice>>>,
// PCI 设备映射
pci_devices: HashMap<u32, Arc<Mutex<dyn PciDevice>>>,
// MMIO 设备
mmio_devices: Vec<Arc<Mutex<dyn MmioDevice>>>,
// 中断控制器
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
// 控制台设备
console_devices: Vec<Arc<Mutex<virtio_devices::Console>>>,
// 网络设备
net_devices: Vec<Arc<Mutex<virtio_devices::Net>>>,
// 块设备
block_devices: Vec<Arc<Mutex<virtio_devices::Block>>>,
// 文件系统设备
fs_devices: Vec<Arc<Mutex<virtio_devices::Fs>>>,
// 串口设备
serial_devices: Vec<Arc<Mutex<serial::Serial>>>,
// 配置
config: DeviceConfig,
vm_config: VmConfig,
// 中断管理
interrupt_sources: Vec<Arc<Mutex<InterruptSourceGroup>>>,
// ACPI
acpi_table: Arc<Mutex<AcpiTable>>,
// 快照
bus_devices: Vec<BusDevice>,
}DeviceConfig
rust
// vmm/src/config.rs
pub struct DeviceConfig {
pub console: ConsoleConfig,
pub serial: SerialConfig,
pub net: Vec<NetConfig>,
pub disk: Vec<DiskConfig>,
pub fs: Vec<FSConfig>,
pub pmem: Vec<PmemConfig>,
pub devices: Vec<DeviceConfig>,
pub iommu: bool,
}设备初始化流程
初始化时序
实现代码
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn new(
config: DeviceConfig,
vm_config: VmConfig,
guest_memory: GuestMemoryMmap,
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
msi_device_manager: &MsiDeviceManager,
mmio_bus: Arc<Bus>,
io_bus: Arc<Bus>,
) -> Result<Self> {
// 1. 创建中断控制器
let interrupt_controller = interrupt_controller
.or_else(|| Some(Arc::new(Mutex::new(IoApic::new()?))))
.ok_or(Error::InterruptControllerCreation)?;
// 2. 创建 PCI Root
let pci_root = PciRoot::new()?;
// 3. 创建 Virtio 设备
let mut devices = Vec::new();
// 块设备
for disk_config in &config.disk {
let block = Self::create_block_device(disk_config, &guest_memory)?;
devices.push(Arc::new(Mutex::new(block)) as Arc<Mutex<dyn PciDevice>>);
}
// 网络设备
for net_config in &config.net {
let net = Self::create_net_device(net_config)?;
devices.push(Arc::new(Mutex::new(net)) as Arc<Mutex<dyn PciDevice>>);
}
// 文件系统设备
for fs_config in &config.fs {
let fs = Self::create_fs_device(fs_config)?;
devices.push(Arc::new(Mutex::new(fs)) as Arc<Mutex<dyn PciDevice>>);
}
// 控制台设备
let console = Self::create_console_device(&config.console)?;
devices.push(Arc::new(Mutex::new(console)) as Arc<Mutex<dyn PciDevice>>);
// 串口设备
let serial = Self::create_serial_device(&config.serial)?;
devices.push(Arc::new(Mutex::new(serial)) as Arc<Mutex<dyn PciDevice>>);
// Balloon 设备
let balloon = Self::create_balloon_device()?;
devices.push(Arc::new(Mutex::new(balloon)) as Arc<Mutex<dyn PciDevice>>);
// 4. 创建 MMIO 设备
let mut mmio_devices = Vec::new();
// 5. 创建传统设备
let mut serial_devices = Vec::new();
Ok(Self {
devices,
pci_devices: HashMap::new(),
mmio_devices,
interrupt_controller: Some(interrupt_controller),
console_devices: Vec::new(),
net_devices: Vec::new(),
block_devices: Vec::new(),
fs_devices: Vec::new(),
serial_devices,
config,
vm_config,
interrupt_sources: Vec::new(),
acpi_table: Arc::new(Mutex::new(AcpiTable::new())),
bus_devices: Vec::new(),
})
}
}Virtio 设备创建
块设备
rust
// vmm/src/device_manager.rs
impl DeviceManager {
fn create_block_device(
config: &DiskConfig,
guest_memory: &GuestMemoryMmap,
) -> Result<virtio_devices::Block> {
// 打开磁盘文件
let disk_file = OpenOptions::new()
.read(true)
.write(!config.readonly)
.open(&config.path)?;
// 创建 Virtio-blk 设备
let block = virtio_devices::Block::new(
disk_file,
config.readonly,
config.direct,
config.iommu,
config.num_queues,
config.queue_size,
)?;
// 配置中断
block.set_irq(PciInterruptLine::IntX);
Ok(block)
}
}网络设备
rust
// vmm/src/device_manager.rs
impl DeviceManager {
fn create_net_device(
config: &NetConfig,
) -> Result<virtio_devices::Net> {
// 打开网络设备
let net_dev = virtio_devices::Net::new(
&config.tap,
config.mac,
config.mtu,
config.iommu,
config.num_queues,
config.queue_size,
)?;
// 配置中断
net_dev.set_irq(PciInterruptLine::IntX);
Ok(net_dev)
}
}文件系统设备
rust
// vmm/src/device_manager.rs
impl DeviceManager {
fn create_fs_device(
config: &FSConfig,
) -> Result<virtio_devices::Fs> {
// 创建 Virtio-fs 设备
let fs = virtio_devices::Fs::new(
&config.tag,
&config.sock,
config.num_queues,
config.queue_size,
config.queue_size_worker,
)?;
// 配置中断
fs.set_irq(PciInterruptLine::IntX);
Ok(fs)
}
}控制台设备
rust
// vmm/src/device_manager.rs
impl DeviceManager {
fn create_console_device(
config: &ConsoleConfig,
) -> Result<virtio_devices::Console> {
// 创建控制台设备
let console = virtio_devices::Console::new(
config.stdin,
config.stdout,
config.iommu,
)?;
// 配置输入输出
if config.stdin {
console.set_input(BufReader::new(io::stdin()));
}
if config.stdout {
console.set_output(BufWriter::new(io::stdout()));
}
// 配置中断
console.set_irq(PciInterruptLine::IntX);
Ok(console)
}
}设备挂载
PCI 挂载
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn attach_pci_device(
&mut self,
device: Arc<Mutex<dyn PciDevice>>,
) -> Result<u32> {
// 1. 分配 PCI 地址
let pci_address = self.pci_root.allocate_address()?;
// 2. 挂载到 PCI Root
self.pci_root.attach_device(
device.clone(),
pci_address,
)?;
// 3. 存储设备映射
self.pci_devices.insert(pci_address, device.clone());
// 4. 配置 BAR
self.configure_pci_bar(device, pci_address)?;
// 5. 映射 MMIO
self.map_pci_mmio(device, pci_address)?;
Ok(pci_address)
}
}MMIO 挂载
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn attach_mmio_device(
&mut self,
device: Arc<Mutex<dyn MmioDevice>>,
base_address: u64,
) -> Result<()> {
// 1. 获取设备信息
let size = device.lock().unwrap().size();
// 2. 映射到 MMIO 总线
self.mmio_bus.insert_device(
device.clone(),
base_address,
size,
)?;
// 3. 存储设备列表
self.mmio_devices.push(device);
Ok(())
}
}中断管理
中断配置
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn configure_interrupts(
&mut self,
device: &Arc<Mutex<dyn PciDevice>>,
interrupt_line: PciInterruptLine,
) -> Result<()> {
// 1. 创建中断源
let interrupt_source = self.create_interrupt_source(
interrupt_line,
)?;
// 2. 配置中断控制器
self.interrupt_controller.lock().unwrap()
.configure_interrupt(
interrupt_line,
interrupt_source.clone(),
)?;
// 3. 存储中断源
self.interrupt_sources.push(interrupt_source);
Ok(())
}
fn create_interrupt_source(
&self,
interrupt_line: PciInterruptLine,
) -> Result<Arc<Mutex<InterruptSourceGroup>>> {
// 根据中断类型创建
match interrupt_line {
PciInterruptLine::IntX => {
// INTx 中断
Ok(Arc::new(Mutex::new(IntxInterruptGroup::new()?)))
}
PciInterruptLine::Msi => {
// MSI 中断
Ok(Arc::new(Mutex::new(MsiInterruptGroup::new()?)))
}
PciInterruptLine::MsiX => {
// MSI-X 中断
Ok(Arc::new(Mutex::new(MsixInterruptGroup::new()?)))
}
}
}
}中断触发
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn trigger_interrupt(
&self,
device_id: u32,
interrupt_index: usize,
) -> Result<()> {
// 1. 获取中断源
let interrupt_source = self.get_interrupt_source(device_id)?;
// 2. 触发中断
interrupt_source.lock().unwrap()
.trigger_interrupt(interrupt_index)?;
// 3. 通知中断控制器
self.interrupt_controller.lock().unwrap()
.trigger_interrupt(device_id, interrupt_index)?;
Ok(())
}
}设备热插拔
热插拔流程
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn hotplug_device(
&mut self,
device_config: DeviceConfig,
) -> Result<()> {
// 1. 创建设备
let device = match device_config {
DeviceConfig::Disk(config) => {
Arc::new(Mutex::new(Self::create_block_device(&config, &self.guest_memory)?))
}
DeviceConfig::Net(config) => {
Arc::new(Mutex::new(Self::create_net_device(&config)?))
}
// ...
};
// 2. 挂载设备
let pci_address = self.attach_pci_device(device.clone())?;
// 3. 通知 Guest
self.notify_hotplug_acpi(pci_address)?;
Ok(())
}
pub fn hotremove_device(
&mut self,
pci_address: u32,
) -> Result<()> {
// 1. 获取设备
let device = self.pci_devices.get(&pci_address)
.ok_or(Error::DeviceNotFound)?;
// 2. 通知 Guest
self.notify_hotremove_acpi(pci_address)?;
// 3. 断开设备
self.pci_root.detach_device(pci_address)?;
// 4. 移除设备
self.pci_devices.remove(&pci_address);
Ok(())
}
}快照
设备快照
rust
// vmm/src/device_manager.rs
impl DeviceManager {
pub fn snapshot(&self) -> Result<DeviceManagerSnapshotData> {
let mut snapshot = Snapshot::new(DEVICE_MANAGER_SNAPSHOT_ID);
// 保存每个设备的状态
for (pci_address, device) in &self.pci_devices {
let device_snapshot = device.lock().unwrap().snapshot()?;
snapshot.add_data_section(
SnapshotDataSection::new_from_state(&device_snapshot)?
);
}
// 保存 MMIO 设备状态
for device in &self.mmio_devices {
let device_snapshot = device.lock().unwrap().snapshot()?;
snapshot.add_data_section(
SnapshotDataSection::new_from_state(&device_snapshot)?
);
}
// 保存中断控制器状态
if let Some(interrupt_controller) = &self.interrupt_controller {
let controller_snapshot = interrupt_controller.lock().unwrap().snapshot()?;
snapshot.add_data_section(
SnapshotDataSection::new_from_state(&controller_snapshot)?
);
}
Ok(snapshot)
}
}错误处理
错误类型
rust
// vmm/src/device_manager.rs
#[derive(Debug, Error)]
pub enum Error {
#[error("Failed to create device: {0}")]
CreateDevice(#[source] io::Error),
#[error("Failed to attach device to PCI: {0}")]
AttachPciDevice(#[source] PciRootError),
#[error("Failed to map device MMIO: {0}")]
MapMmio(#[source] io::Error),
#[error("Failed to configure interrupts: {0}")]
ConfigureInterrupts(#[source] InterruptControllerError),
#[error("Device not found: {0}")]
DeviceNotFound(u32),
#[error("Failed to hotplug device: {0}")]
HotplugDevice(#[source] io::Error),
// ...
}下一步
- 深入 Hypervisor 抽象层
- 了解 Virtio 设备