Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/vhost_user_backend/connection.rs
5394 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
pub mod sys;
6
use std::any::Any;
7
use std::pin::Pin;
8
9
use cros_async::Executor;
10
use futures::Future;
11
12
use crate::virtio::vhost_user_backend::handler::DeviceRequestHandler;
13
use crate::virtio::vhost_user_backend::handler::VhostUserDevice;
14
use crate::virtio::vhost_user_backend::VhostUserDeviceBuilder;
15
use crate::virtio::vhost_user_backend::VhostUserListener;
16
use crate::virtio::vhost_user_backend::VhostUserStream;
17
18
pub enum BackendConnection {
19
Listener(VhostUserListener),
20
Stream(VhostUserStream),
21
}
22
23
/// Trait that the platform-specific type `VhostUserConnection` needs to implement. It contains all
24
/// the methods that are ok to call from non-platform specific code.
25
pub trait VhostUserConnectionTrait {
26
/// Take and return resources owned by the parent process in case of a incoming fork.
27
///
28
/// This method needs to be called only if you are going to use the connection in a jailed child
29
/// process. In this case, the connection will belong to the child and the parent will drop it,
30
/// but the child may lack the rights to drop some resources created at construction time. One
31
/// such example is the socket file of a regular vhost-user device, that cannot be dropped by
32
/// the child unless it gets extra permissions.
33
///
34
/// This method returns an opaque object that, upon being dropped, will free these resources.
35
/// That way, the child process does not need extra rights to clear them, and the parent can
36
/// drop the connection after forking and just need to keep that object alive until the child
37
/// exits to do housekeeping properly.
38
///
39
/// The default implementation returns nothing as that's what most connection would need anyway.
40
fn take_parent_process_resources(&mut self) -> Option<Box<dyn Any>> {
41
None
42
}
43
44
/// Returns a `Future` that processes requests for `handler`. The future exits when the
45
/// front-end side disconnects or an error occurs.
46
fn run_req_handler<'e>(
47
self,
48
handler: Box<dyn vmm_vhost::Backend>,
49
ex: &'e Executor,
50
) -> Pin<Box<dyn Future<Output = anyhow::Result<()>> + 'e>>;
51
52
/// Returns a `Future` that will process requests from `backend` when polled. The future exits
53
/// when the front-end side disconnects or an error occurs.
54
///
55
/// This is a legacy way to run devices - prefer `run_device`.
56
fn run_backend<'e>(
57
self,
58
backend: impl VhostUserDevice + 'static,
59
ex: &'e Executor,
60
) -> Pin<Box<dyn Future<Output = anyhow::Result<()>> + 'e>>
61
where
62
Self: Sized,
63
{
64
self.run_req_handler(Box::new(DeviceRequestHandler::new(backend)), ex)
65
}
66
67
/// Start processing requests for a `VhostUserDevice` on `connection`. Returns when the
68
/// front-end side disconnects or an error occurs.
69
fn run_device(self, ex: Executor, device: Box<dyn VhostUserDeviceBuilder>) -> anyhow::Result<()>
70
where
71
Self: Sized,
72
{
73
ex.run_until(self.run_req_handler(device.build(&ex).unwrap(), &ex))?
74
}
75
}
76
77