diff --git a/src/cross_domain/atomic_memory_sentinel_manager.rs b/src/cross_domain/atomic_memory_sentinel_manager.rs index 389fc44..72605e0 100644 --- a/src/cross_domain/atomic_memory_sentinel_manager.rs +++ b/src/cross_domain/atomic_memory_sentinel_manager.rs @@ -19,10 +19,8 @@ use mesa3d_util::AtomicMemorySentinel; use mesa3d_util::Event; use mesa3d_util::MemoryMapping; use mesa3d_util::MesaError; -use mesa3d_util::OwnedDescriptor; -use crate::rutabaga_core::VirtioFsKey; -use crate::rutabaga_core::VirtioFsTable; +use crate::rutabaga_core::VirtioFsLookup; use crate::rutabaga_utils::RutabagaError; use crate::rutabaga_utils::RutabagaResult; use crate::rutabaga_utils::RUTABAGA_MAP_ACCESS_RW; @@ -125,15 +123,15 @@ impl Drop for SentinelInstance { /// Manager for all atomic memory sentinel watchers pub struct AtomicMemorySentinelManager { watchers: Map, - virtiofs_table: Option, + virtiofs_lookup: Option>, } impl AtomicMemorySentinelManager { /// Creates a new AtomicMemorySentinelManager - pub fn new(virtiofs_table: Option) -> Self { + pub fn new(virtiofs_lookup: Option>) -> Self { Self { watchers: Map::new(), - virtiofs_table, + virtiofs_lookup, } } @@ -143,20 +141,12 @@ impl AtomicMemorySentinelManager { return Err(RutabagaError::AlreadyInUse); } - let virtiofs_table = self - .virtiofs_table + let virtiofs_lookup = self + .virtiofs_lookup .as_ref() .ok_or(RutabagaError::InvalidCrossDomainItemId)?; - let virtiofs = virtiofs_table.lock().unwrap(); - let key = VirtioFsKey { fs_id, handle }; - let file = virtiofs - .get(&key) - .ok_or(RutabagaError::InvalidCrossDomainItemId)? - .try_clone() - .map_err(MesaError::IoError)?; - - let handle = OwnedDescriptor::from(file); + let handle = virtiofs_lookup.get_exported_descriptor(fs_id, handle)?; let mapping = MemoryMapping::from_safe_descriptor( handle, size_of::(), diff --git a/src/cross_domain/mod.rs b/src/cross_domain/mod.rs index 073af15..e32f0da 100644 --- a/src/cross_domain/mod.rs +++ b/src/cross_domain/mod.rs @@ -44,7 +44,7 @@ use crate::handle::RutabagaHandle; use crate::rutabaga_core::RutabagaComponent; use crate::rutabaga_core::RutabagaContext; use crate::rutabaga_core::RutabagaResource; -use crate::rutabaga_core::VirtioFsTable; +use crate::rutabaga_core::VirtioFsLookup; use crate::rutabaga_utils::Resource3DInfo; use crate::rutabaga_utils::ResourceCreateBlob; use crate::rutabaga_utils::RutabagaComponentType; @@ -146,7 +146,7 @@ pub struct CrossDomain { paths: Option>, gralloc: Arc>, fence_handler: RutabagaFenceHandler, - virtiofs_table: Option, + virtiofs_lookup: Option>, } // TODO(gurchetansingh): optimize the item tracker. Each requirements blob is long-lived and can @@ -587,14 +587,14 @@ impl CrossDomain { pub fn init( paths: Option>, fence_handler: RutabagaFenceHandler, - virtiofs_table: Option, + virtiofs_lookup: Option>, ) -> RutabagaResult> { let gralloc = RutabagaGralloc::new(RutabagaGrallocBackendFlags::new())?; Ok(Box::new(CrossDomain { paths, gralloc: Arc::new(Mutex::new(gralloc)), fence_handler, - virtiofs_table, + virtiofs_lookup, })) } } @@ -1280,7 +1280,7 @@ impl RutabagaComponent for CrossDomain { context_resources: Arc::new(Mutex::new(Default::default())), item_state: Arc::new(Mutex::new(Default::default())), sentinel_manager: Arc::new(Mutex::new(AtomicMemorySentinelManager::new( - self.virtiofs_table.clone(), + self.virtiofs_lookup.clone(), ))), fence_handler, worker_thread: None, diff --git a/src/lib.rs b/src/lib.rs index c79764a..991b766 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,7 @@ pub use crate::rutabaga_core::calculate_capset_mask; pub use crate::rutabaga_core::calculate_capset_names; pub use crate::rutabaga_core::Rutabaga; pub use crate::rutabaga_core::RutabagaBuilder; +pub use crate::rutabaga_core::VirtioFsLookup; pub use crate::rutabaga_gralloc::DrmFormat; pub use crate::rutabaga_gralloc::ImageAllocationInfo; pub use crate::rutabaga_gralloc::ImageMemoryRequirements; diff --git a/src/rutabaga_core.rs b/src/rutabaga_core.rs index 259926e..750caa9 100644 --- a/src/rutabaga_core.rs +++ b/src/rutabaga_core.rs @@ -5,11 +5,10 @@ //! rutabaga_core: Cross-platform, Rust-based, Wayland and Vulkan centric GPU virtualization. use std::collections::BTreeMap as Map; use std::convert::TryInto; -use std::fs::File; use std::io::IoSlice; use std::io::IoSliceMut; use std::path::Path; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use mesa3d_util::MemoryMapping; use mesa3d_util::MesaError; @@ -64,17 +63,15 @@ use crate::snapshot::RutabagaSnapshotWriter; use crate::virgl_renderer::VirglRenderer; use crate::RutabagaPaths; -/// Key for identifying a file in the VirtioFS table. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct VirtioFsKey { - /// VirtioFS filesystem ID (identifies which virtio-fs instance) - pub fs_id: u64, - /// File handle within the filesystem (identifies a specific file) - pub handle: u64, +/// Trait for looking up exported file descriptors from virtio-fs. +/// +/// Allows VMMs to use different data structures and concurrency strategies. +/// The trait can be extended in the future to support inode-based lookups for O_PATH fds. +pub trait VirtioFsLookup: Send + Sync { + /// Retrieves an exported file descriptor by filesystem ID and handle. + fn get_exported_descriptor(&self, fs_id: u64, handle: u64) -> RutabagaResult; } -pub type VirtioFsTable = Arc>>; - const RUTABAGA_DEFAULT_WIDTH: u32 = 1280; const RUTABAGA_DEFAULT_HEIGHT: u32 = 1024; @@ -1301,7 +1298,7 @@ pub struct RutabagaBuilder { debug_handler: Option, renderer_features: Option, server_descriptor: Option, - virtiofs_table: Option, + virtiofs_lookup: Option>, } impl RutabagaBuilder { @@ -1323,7 +1320,7 @@ impl RutabagaBuilder { debug_handler: None, renderer_features: None, server_descriptor: None, - virtiofs_table: None, + virtiofs_lookup: None, } } @@ -1428,9 +1425,12 @@ impl RutabagaBuilder { self } - /// Set export table for the RutabagaBuilder - pub fn set_export_table(mut self, virtiofs_table: VirtioFsTable) -> RutabagaBuilder { - self.virtiofs_table = Some(virtiofs_table); + /// Set VirtioFS lookup implementation for the RutabagaBuilder + pub fn set_virtiofs_lookup( + mut self, + virtiofs_lookup: Arc, + ) -> RutabagaBuilder { + self.virtiofs_lookup = Some(virtiofs_lookup); self } @@ -1551,7 +1551,7 @@ impl RutabagaBuilder { let cross_domain = CrossDomain::init( self.paths.clone(), self.fence_handler.clone(), - self.virtiofs_table.clone(), + self.virtiofs_lookup.clone(), )?; rutabaga_components.insert(RutabagaComponentType::CrossDomain, cross_domain); push_capset(RUTABAGA_CAPSET_CROSS_DOMAIN); diff --git a/src/rutabaga_utils.rs b/src/rutabaga_utils.rs index 1621151..e7cd346 100644 --- a/src/rutabaga_utils.rs +++ b/src/rutabaga_utils.rs @@ -651,7 +651,6 @@ pub const RUTABAGA_HANDLE_TYPE_PLATFORM_SCREEN_BUFFER_QNX: u32 = 0x01000000; pub const RUTABAGA_HANDLE_TYPE_PLATFORM_EGL_NATIVE_PIXMAP: u32 = 0x02000000; pub const RUTABAGA_HANDLE_TYPE_PLATFORM_AHB: u32 = 0x03000000; - #[derive(Clone)] pub struct RutabagaHandler { closure: Arc,