Skip to content
This repository was archived by the owner on Oct 24, 2022. It is now read-only.

Commit 70f668a

Browse files
jiangliustefano-garzarella
authored andcommitted
doc: refine README.md
Refine README.md, help is needed to improve documentation for publishing. Signed-off-by: Liu Jiang <[email protected]>
1 parent f2e38e2 commit 70f668a

File tree

1 file changed

+98
-7
lines changed

1 file changed

+98
-7
lines changed

README.md

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,104 @@
22

33
## Design
44

5-
This crate provides convenient abstractions for implementing `vhost-user` device server backends:
6-
7-
- A vhost-user backend trait (`VhostUserBackend`)
8-
- A public API for the backend to interact with (`VhostUserDaemon`)
9-
- An structure including virtio queue related elements (`Vring`)
10-
- A worker for receiving queue events and forwarding them to the backend.
5+
The `vhost-user-backend` crate provides a framework to implement `vhost-user` backend services,
6+
which includes following external public APIs:
7+
- A daemon control object (`VhostUserDaemon`) to start and stop the service daemon.
8+
- A vhost-user backend trait (`VhostUserBackendMut`) to handle vhost-user control messages and virtio
9+
messages.
10+
- A vring access trait (`VringT`) to access virtio queues, and three implementations of the trait:
11+
`VringState`, `VringMutex` and `VringRwLock`.
1112

1213
## Usage
14+
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`:
15+
```rust
16+
pub struct VhostUserDaemon<S, V, B = ()>
17+
where
18+
S: VhostUserBackend<V, B>,
19+
V: VringT<GM<B>> + Clone + Send + Sync + 'static,
20+
B: Bitmap + 'static,
21+
{
22+
pub fn new(name: String, backend: S, atomic_mem: GuestMemoryAtomic<GuestMemoryMmap<B>>) -> Result<Self>;
23+
pub fn start(&mut self, listener: Listener) -> Result<()>;
24+
pub fn wait(&mut self) -> Result<()>;
25+
pub fn get_epoll_handlers(&self) -> Vec<Arc<VringEpollHandler<S, V, B>>>;
26+
}
27+
```
28+
29+
### Create a `VhostUserDaemon` Instance
30+
The `VhostUserDaemon::new()` creates an instance of `VhostUserDaemon` object. The client needs to
31+
pass in an `VhostUserBackend` object, which will be used to configure the `VhostUserDaemon`
32+
instance, handle control messages from the vhost-user master and handle virtio requests from
33+
virtio queues. A group of working threads will be created to handle virtio requests from configured
34+
virtio queues.
35+
36+
### Start the `VhostUserDaemon`
37+
The `VhostUserDaemon::start()` method waits for an incoming connection from the vhost-user masters
38+
on the `listener`. Once a connection is ready, a main thread will be created to handle vhost-user
39+
messages from the vhost-user master.
40+
41+
### Stop the `VhostUserDaemon`
42+
The `VhostUserDaemon::stop()` method waits for the main thread to exit. An exit event must be sent
43+
to the main thread by writing to the `exit_event` EventFd before waiting for it to exit.
44+
45+
### Threading Model
46+
The main thread and virtio queue working threads will concurrently access the underlying virtio
47+
queues, so all virtio queue in multi-threading model. But the main thread only accesses virtio
48+
queues for configuration, so client could adopt locking policies to optimize for the virtio queue
49+
working threads.
50+
51+
## Example
52+
Example code to handle virtio messages from a virtio queue:
53+
```rust
54+
impl VhostUserBackendMut for VhostUserService {
55+
fn process_queue(&mut self, vring: &VringMutex) -> Result<bool> {
56+
let mut used_any = false;
57+
let mem = match &self.mem {
58+
Some(m) => m.memory(),
59+
None => return Err(Error::NoMemoryConfigured),
60+
};
61+
62+
let mut vring_state = vring.get_mut();
63+
64+
while let Some(avail_desc) = vring_state
65+
.get_queue_mut()
66+
.iter()
67+
.map_err(|_| Error::IterateQueue)?
68+
.next()
69+
{
70+
// Process the request...
71+
72+
if self.event_idx {
73+
if vring_state.add_used(head_index, 0).is_err() {
74+
warn!("Couldn't return used descriptors to the ring");
75+
}
76+
77+
match vring_state.needs_notification() {
78+
Err(_) => {
79+
warn!("Couldn't check if queue needs to be notified");
80+
vring_state.signal_used_queue().unwrap();
81+
}
82+
Ok(needs_notification) => {
83+
if needs_notification {
84+
vring_state.signal_used_queue().unwrap();
85+
}
86+
}
87+
}
88+
} else {
89+
if vring_state.add_used(head_index, 0).is_err() {
90+
warn!("Couldn't return used descriptors to the ring");
91+
}
92+
vring_state.signal_used_queue().unwrap();
93+
}
94+
}
95+
96+
Ok(used_any)
97+
}
98+
}
99+
```
100+
101+
## License
102+
103+
This project is licensed under
13104

14-
Users of this create are expected to implement the `VhostUserBackend` trait and to initialize the execution context by instantiating `VhostUserDaemon` and calling to its `start` method.
105+
- [Apache License](http://www.apache.org/licenses/LICENSE-2.0), Version 2.0

0 commit comments

Comments
 (0)