about summary refs log tree commit diff
path: root/tvix/store/src/fs/virtiofs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/store/src/fs/virtiofs.rs')
-rw-r--r--tvix/store/src/fs/virtiofs.rs237
1 files changed, 0 insertions, 237 deletions
diff --git a/tvix/store/src/fs/virtiofs.rs b/tvix/store/src/fs/virtiofs.rs
deleted file mode 100644
index 846270d28568..000000000000
--- a/tvix/store/src/fs/virtiofs.rs
+++ /dev/null
@@ -1,237 +0,0 @@
-use std::{
-    convert, error, fmt, io,
-    ops::Deref,
-    path::Path,
-    sync::{Arc, MutexGuard, RwLock},
-};
-
-use fuse_backend_rs::{
-    api::{filesystem::FileSystem, server::Server},
-    transport::{FsCacheReqHandler, Reader, VirtioFsWriter},
-};
-use tracing::error;
-use vhost::vhost_user::{
-    Listener, SlaveFsCacheReq, VhostUserProtocolFeatures, VhostUserVirtioFeatures,
-};
-use vhost_user_backend::{VhostUserBackendMut, VhostUserDaemon, VringMutex, VringState, VringT};
-use virtio_bindings::bindings::virtio_ring::{
-    VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC,
-};
-use virtio_queue::QueueT;
-use vm_memory::{GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap};
-use vmm_sys_util::epoll::EventSet;
-
-const VIRTIO_F_VERSION_1: u32 = 32;
-const NUM_QUEUES: usize = 2;
-const QUEUE_SIZE: usize = 1024;
-
-#[derive(Debug)]
-enum Error {
-    /// Failed to handle non-input event.
-    HandleEventNotEpollIn,
-    /// Failed to handle unknown event.
-    HandleEventUnknownEvent,
-    /// Invalid descriptor chain.
-    InvalidDescriptorChain,
-    /// Failed to handle filesystem requests.
-    HandleRequests(fuse_backend_rs::Error),
-    /// Failed to construct new vhost user daemon.
-    NewDaemon,
-    /// Failed to start the vhost user daemon.
-    StartDaemon,
-    /// Failed to wait for the vhost user daemon.
-    WaitDaemon,
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "vhost_user_fs_error: {self:?}")
-    }
-}
-
-impl error::Error for Error {}
-
-impl convert::From<Error> for io::Error {
-    fn from(e: Error) -> Self {
-        io::Error::new(io::ErrorKind::Other, e)
-    }
-}
-
-struct VhostUserFsBackend<FS>
-where
-    FS: FileSystem + Send + Sync,
-{
-    server: Arc<Server<Arc<FS>>>,
-    event_idx: bool,
-    guest_mem: GuestMemoryAtomic<GuestMemoryMmap>,
-    cache_req: Option<SlaveFsCacheReq>,
-}
-
-impl<FS> VhostUserFsBackend<FS>
-where
-    FS: FileSystem + Send + Sync,
-{
-    fn process_queue(&mut self, vring: &mut MutexGuard<VringState>) -> std::io::Result<bool> {
-        let mut used_descs = false;
-
-        while let Some(desc_chain) = vring
-            .get_queue_mut()
-            .pop_descriptor_chain(self.guest_mem.memory())
-        {
-            let memory = desc_chain.memory();
-            let reader = Reader::from_descriptor_chain(memory, desc_chain.clone())
-                .map_err(|_| Error::InvalidDescriptorChain)?;
-            let writer = VirtioFsWriter::new(memory, desc_chain.clone())
-                .map_err(|_| Error::InvalidDescriptorChain)?;
-
-            self.server
-                .handle_message(
-                    reader,
-                    writer.into(),
-                    self.cache_req
-                        .as_mut()
-                        .map(|req| req as &mut dyn FsCacheReqHandler),
-                    None,
-                )
-                .map_err(Error::HandleRequests)?;
-
-            // TODO: Is len 0 correct?
-            if let Err(error) = vring
-                .get_queue_mut()
-                .add_used(memory, desc_chain.head_index(), 0)
-            {
-                error!(?error, "failed to add desc back to ring");
-            }
-
-            // TODO: What happens if we error out before here?
-            used_descs = true;
-        }
-
-        let needs_notification = if self.event_idx {
-            match vring
-                .get_queue_mut()
-                .needs_notification(self.guest_mem.memory().deref())
-            {
-                Ok(needs_notification) => needs_notification,
-                Err(error) => {
-                    error!(?error, "failed to check if queue needs notification");
-                    true
-                }
-            }
-        } else {
-            true
-        };
-
-        if needs_notification {
-            if let Err(error) = vring.signal_used_queue() {
-                error!(?error, "failed to signal used queue");
-            }
-        }
-
-        Ok(used_descs)
-    }
-}
-
-impl<FS> VhostUserBackendMut<VringMutex> for VhostUserFsBackend<FS>
-where
-    FS: FileSystem + Send + Sync,
-{
-    fn num_queues(&self) -> usize {
-        NUM_QUEUES
-    }
-
-    fn max_queue_size(&self) -> usize {
-        QUEUE_SIZE
-    }
-
-    fn features(&self) -> u64 {
-        1 << VIRTIO_F_VERSION_1
-            | 1 << VIRTIO_RING_F_INDIRECT_DESC
-            | 1 << VIRTIO_RING_F_EVENT_IDX
-            | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()
-    }
-
-    fn protocol_features(&self) -> VhostUserProtocolFeatures {
-        VhostUserProtocolFeatures::MQ | VhostUserProtocolFeatures::SLAVE_REQ
-    }
-
-    fn set_event_idx(&mut self, enabled: bool) {
-        self.event_idx = enabled;
-    }
-
-    fn update_memory(&mut self, _mem: GuestMemoryAtomic<GuestMemoryMmap>) -> std::io::Result<()> {
-        // This is what most the vhost user implementations do...
-        Ok(())
-    }
-
-    fn set_slave_req_fd(&mut self, cache_req: SlaveFsCacheReq) {
-        self.cache_req = Some(cache_req);
-    }
-
-    fn handle_event(
-        &mut self,
-        device_event: u16,
-        evset: vmm_sys_util::epoll::EventSet,
-        vrings: &[VringMutex],
-        _thread_id: usize,
-    ) -> std::io::Result<bool> {
-        if evset != EventSet::IN {
-            return Err(Error::HandleEventNotEpollIn.into());
-        }
-
-        let mut queue = match device_event {
-            // High priority queue
-            0 => vrings[0].get_mut(),
-            // Regurlar priority queue
-            1 => vrings[1].get_mut(),
-            _ => {
-                return Err(Error::HandleEventUnknownEvent.into());
-            }
-        };
-
-        if self.event_idx {
-            loop {
-                queue
-                    .get_queue_mut()
-                    .enable_notification(self.guest_mem.memory().deref())
-                    .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
-                if !self.process_queue(&mut queue)? {
-                    break;
-                }
-            }
-        } else {
-            self.process_queue(&mut queue)?;
-        }
-
-        Ok(false)
-    }
-}
-
-pub fn start_virtiofs_daemon<FS, P>(fs: FS, socket: P) -> io::Result<()>
-where
-    FS: FileSystem + Send + Sync + 'static,
-    P: AsRef<Path>,
-{
-    let guest_mem = GuestMemoryAtomic::new(GuestMemoryMmap::new());
-
-    let server = Arc::new(fuse_backend_rs::api::server::Server::new(Arc::new(fs)));
-
-    let backend = Arc::new(RwLock::new(VhostUserFsBackend {
-        server,
-        guest_mem: guest_mem.clone(),
-        event_idx: false,
-        cache_req: None,
-    }));
-
-    let listener = Listener::new(socket, true).unwrap();
-
-    let mut fs_daemon =
-        VhostUserDaemon::new(String::from("vhost-user-fs-tvix-store"), backend, guest_mem)
-            .map_err(|_| Error::NewDaemon)?;
-
-    fs_daemon.start(listener).map_err(|_| Error::StartDaemon)?;
-
-    fs_daemon.wait().map_err(|_| Error::WaitDaemon)?;
-
-    Ok(())
-}