| 4676 | } |
| 4677 | |
| 4678 | pub fn remove_device(&mut self, id: &str) -> DeviceManagerResult<()> { |
| 4679 | // The node can be directly a PCI node in case the 'id' refers to a |
| 4680 | // VFIO device or a virtio-pci one. |
| 4681 | // In case the 'id' refers to a virtio device, we must find the PCI |
| 4682 | // node by looking at the parent. |
| 4683 | let device_tree = self.device_tree.lock().unwrap(); |
| 4684 | let node = device_tree |
| 4685 | .get(id) |
| 4686 | .ok_or_else(|| DeviceManagerError::UnknownDeviceId(id.to_string()))?; |
| 4687 | |
| 4688 | // Release advisory locks by dropping all references. |
| 4689 | // Linux automatically releases all locks of that file if the last open FD is closed. |
| 4690 | { |
| 4691 | let maybe_block_device_index = self |
| 4692 | .block_devices |
| 4693 | .iter() |
| 4694 | .enumerate() |
| 4695 | .find(|(_, dev)| { |
| 4696 | let dev = dev.lock().unwrap(); |
| 4697 | dev.id() == id |
| 4698 | }) |
| 4699 | .map(|(i, _)| i); |
| 4700 | if let Some(index) = maybe_block_device_index { |
| 4701 | let _ = self.block_devices.swap_remove(index); |
| 4702 | } |
| 4703 | } |
| 4704 | |
| 4705 | let pci_device_node = if node.pci_bdf.is_some() && node.pci_device_handle.is_some() { |
| 4706 | node |
| 4707 | } else { |
| 4708 | let parent = node |
| 4709 | .parent |
| 4710 | .as_ref() |
| 4711 | .ok_or(DeviceManagerError::MissingNode)?; |
| 4712 | device_tree |
| 4713 | .get(parent) |
| 4714 | .ok_or(DeviceManagerError::MissingNode)? |
| 4715 | }; |
| 4716 | |
| 4717 | let pci_device_bdf: PciBdf = pci_device_node |
| 4718 | .pci_bdf |
| 4719 | .ok_or(DeviceManagerError::MissingDeviceNodePciBdf)?; |
| 4720 | let pci_segment_id = pci_device_bdf.segment(); |
| 4721 | |
| 4722 | let pci_device_handle = pci_device_node |
| 4723 | .pci_device_handle |
| 4724 | .as_ref() |
| 4725 | .ok_or(DeviceManagerError::MissingPciDevice)?; |
| 4726 | #[allow(irrefutable_let_patterns)] |
| 4727 | if let PciDeviceHandle::Virtio(virtio_pci_device) = pci_device_handle { |
| 4728 | let device_type = VirtioDeviceType::from( |
| 4729 | virtio_pci_device |
| 4730 | .lock() |
| 4731 | .unwrap() |
| 4732 | .virtio_device() |
| 4733 | .lock() |
| 4734 | .unwrap() |
| 4735 | .device_type(), |