diff --git a/src/runtime-rs/crates/hypervisor/src/device/topology.rs b/src/runtime-rs/crates/hypervisor/src/device/topology.rs index 255996cae6..610fe2e347 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/topology.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/topology.rs @@ -318,6 +318,13 @@ pub enum Strategy { MultipleRootPorts, } +/// Represents an available node in the PCIe topology. +#[derive(Clone, Debug)] +pub enum AvailableNode { + TopologyPortDevice(TopologyPortDevice), + SwitchDownPort(SwitchDownPort), +} + #[derive(Clone, Debug, Default)] pub struct PCIeTopology { pub hypervisor_name: String, @@ -648,6 +655,31 @@ impl PCIeTopology { Ok(()) } + + /// Finds an availabled node in the PCIe topology. + /// Returns the first available node found, either a TopologyPortDevice or a SwitchDownPort. + pub fn find_available_node(&mut self) -> Option { + // search in pcie_port_devices + for port_device in self.pcie_port_devices.values_mut() { + if !port_device.allocated { + port_device.allocated = true; + return Some(AvailableNode::TopologyPortDevice(port_device.clone())); + } + + // search in connected switch's downstream ports + if let Some(switch) = &mut port_device.connected_switch { + for switch_port in switch.switch_ports.values_mut() { + if !switch_port.allocated { + switch_port.allocated = true; + return Some(AvailableNode::SwitchDownPort(switch_port.clone())); + } + } + } + } + + // No available node found + None + } } // do_add_pcie_endpoint do add a device into PCIe topology with pcie endpoint