commit | d527bc0e7637992e9f7fad3ca5d4ec5ff1b012f0 | [log] [tgz] |
---|---|---|
author | Android Build Coastguard Worker <[email protected]> | Fri Sep 29 01:15:15 2023 +0000 |
committer | Android Build Coastguard Worker <[email protected]> | Fri Sep 29 01:15:15 2023 +0000 |
tree | 9ddfa467e5eac89a0f0b7455fec50695495b1f26 | |
parent | ad95b58abdf192504b6847224a9a31fbbf8f2939 [diff] | |
parent | 411e8871f3837a507a6489d5f8ea92a969737864 [diff] |
Snap for 10878163 from 411e8871f3837a507a6489d5f8ea92a969737864 to 24D1-release Change-Id: Idecd04dc39c99483774fc974330a335b4ff032a1
The vhost-user-backend
crate provides a framework to implement vhost-user
backend services, which includes following external public APIs:
VhostUserDaemon
) to start and stop the service daemon.VhostUserBackendMut
) to handle vhost-user control messages and virtio messages.VringT
) to access virtio queues, and three implementations of the trait: VringState
, VringMutex
and VringRwLock
.The vhost-user-backend
crate provides a framework to implement vhost-user backend services. The main interface provided by vhost-user-backend
library is the struct VhostUserDaemon
:
pub struct VhostUserDaemon<S, V, B = ()> where S: VhostUserBackend<V, B>, V: VringT<GM<B>> + Clone + Send + Sync + 'static, B: Bitmap + 'static, { pub fn new(name: String, backend: S, atomic_mem: GuestMemoryAtomic<GuestMemoryMmap<B>>) -> Result<Self>; pub fn start(&mut self, listener: Listener) -> Result<()>; pub fn wait(&mut self) -> Result<()>; pub fn get_epoll_handlers(&self) -> Vec<Arc<VringEpollHandler<S, V, B>>>; }
VhostUserDaemon
InstanceThe VhostUserDaemon::new()
creates an instance of VhostUserDaemon
object. The client needs to pass in an VhostUserBackend
object, which will be used to configure the VhostUserDaemon
instance, handle control messages from the vhost-user master and handle virtio requests from virtio queues. A group of working threads will be created to handle virtio requests from configured virtio queues.
VhostUserDaemon
The VhostUserDaemon::start()
method waits for an incoming connection from the vhost-user masters on the listener
. Once a connection is ready, a main thread will be created to handle vhost-user messages from the vhost-user master.
VhostUserDaemon
The VhostUserDaemon::stop()
method waits for the main thread to exit. An exit event must be sent to the main thread by writing to the exit_event
EventFd before waiting for it to exit.
The main thread and virtio queue working threads will concurrently access the underlying virtio queues, so all virtio queue in multi-threading model. But the main thread only accesses virtio queues for configuration, so client could adopt locking policies to optimize for the virtio queue working threads.
Example code to handle virtio messages from a virtio queue:
impl VhostUserBackendMut for VhostUserService { fn process_queue(&mut self, vring: &VringMutex) -> Result<bool> { let mut used_any = false; let mem = match &self.mem { Some(m) => m.memory(), None => return Err(Error::NoMemoryConfigured), }; let mut vring_state = vring.get_mut(); while let Some(avail_desc) = vring_state .get_queue_mut() .iter() .map_err(|_| Error::IterateQueue)? .next() { // Process the request... if self.event_idx { if vring_state.add_used(head_index, 0).is_err() { warn!("Couldn't return used descriptors to the ring"); } match vring_state.needs_notification() { Err(_) => { warn!("Couldn't check if queue needs to be notified"); vring_state.signal_used_queue().unwrap(); } Ok(needs_notification) => { if needs_notification { vring_state.signal_used_queue().unwrap(); } } } } else { if vring_state.add_used(head_index, 0).is_err() { warn!("Couldn't return used descriptors to the ring"); } vring_state.signal_used_queue().unwrap(); } } Ok(used_any) } }
Supporting Xen requires special handling while mapping the guest memory. The vm-memory
crate implements xen memory mapping support via a separate feature xen
, and this crate uses the same feature name to enable Xen support.
Also, for xen mappings, the memory regions passed by the frontend contains few extra fields as described in the vhost-user protocol documentation.
It was decided by the rust-vmm
maintainers to keep the interface simple and build the crate for either standard Unix memory mapping or Xen, and not both.
This project is licensed under