• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 mod listener;
6 mod stream;
7 
8 use std::future::Future;
9 use std::pin::Pin;
10 
11 use anyhow::bail;
12 use anyhow::Result;
13 use base::warn;
14 use base::AsRawDescriptor;
15 use base::RawDescriptor;
16 use cros_async::Executor;
17 pub use listener::VhostUserListener;
18 pub use stream::VhostUserStream;
19 
20 use crate::virtio::vhost::user::device::BackendConnection;
21 use crate::virtio::vhost::user::VhostUserConnectionTrait;
22 use crate::virtio::vhost::user::VhostUserDevice;
23 use crate::virtio::vhost::user::VhostUserDeviceBuilder;
24 
25 impl BackendConnection {
from_opts( socket: Option<&str>, socket_path: Option<&str>, fd: Option<RawDescriptor>, ) -> Result<BackendConnection>26     pub fn from_opts(
27         socket: Option<&str>,
28         socket_path: Option<&str>,
29         fd: Option<RawDescriptor>,
30     ) -> Result<BackendConnection> {
31         let socket_path = if let Some(socket_path) = socket_path {
32             Some(socket_path)
33         } else if let Some(socket) = socket {
34             warn!("--socket is deprecated; please use --socket-path instead");
35             Some(socket)
36         } else {
37             None
38         };
39 
40         match (socket_path, fd) {
41             (Some(socket), None) => {
42                 let listener = VhostUserListener::new(socket)?;
43                 Ok(BackendConnection::Listener(listener))
44             }
45             (None, Some(fd)) => {
46                 let stream = VhostUserStream::new_socket_from_fd(fd)?;
47                 Ok(BackendConnection::Stream(stream))
48             }
49             (Some(_), Some(_)) => bail!("Cannot specify both a socket path and a file descriptor"),
50             (None, None) => bail!("Must specify either a socket or a file descriptor"),
51         }
52     }
53 
run_device( self, ex: Executor, device: Box<dyn VhostUserDeviceBuilder>, ) -> anyhow::Result<()>54     pub fn run_device(
55         self,
56         ex: Executor,
57         device: Box<dyn VhostUserDeviceBuilder>,
58     ) -> anyhow::Result<()> {
59         match self {
60             BackendConnection::Listener(listener) => listener.run_device(ex, device),
61             BackendConnection::Stream(stream) => stream.run_device(ex, device),
62         }
63     }
64 
run_backend<'e>( self, backend: impl VhostUserDevice + 'static, ex: &'e Executor, ) -> Pin<Box<dyn Future<Output = anyhow::Result<()>> + 'e>>65     pub fn run_backend<'e>(
66         self,
67         backend: impl VhostUserDevice + 'static,
68         ex: &'e Executor,
69     ) -> Pin<Box<dyn Future<Output = anyhow::Result<()>> + 'e>> {
70         match self {
71             BackendConnection::Listener(listener) => listener.run_backend(backend, ex),
72             BackendConnection::Stream(stream) => stream.run_backend(backend, ex),
73         }
74     }
75 }
76 
77 impl AsRawDescriptor for BackendConnection {
as_raw_descriptor(&self) -> RawDescriptor78     fn as_raw_descriptor(&self) -> RawDescriptor {
79         match self {
80             BackendConnection::Listener(listener) => listener.as_raw_descriptor(),
81             BackendConnection::Stream(stream) => stream.as_raw_descriptor(),
82         }
83     }
84 }
85