• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::sync::Arc;
6 
7 use super::context::Context;
8 use super::error::*;
9 use super::host_device::HostDevice;
10 use super::hotplug::HotplugHandler;
11 use crate::usb::xhci::usb_hub::UsbHub;
12 use crate::usb::xhci::xhci_backend_device_provider::XhciBackendDeviceProvider;
13 use crate::utils::AsyncJobQueue;
14 use crate::utils::{EventHandler, EventLoop, FailHandle};
15 use msg_socket::{MsgReceiver, MsgSender, MsgSocket};
16 use std::mem;
17 use std::os::unix::io::{AsRawFd, RawFd};
18 use std::time::Duration;
19 use sys_util::net::UnixSeqpacket;
20 use sys_util::{error, WatchingEvents};
21 use vm_control::{
22     UsbControlAttachedDevice, UsbControlCommand, UsbControlResult, UsbControlSocket,
23     USB_CONTROL_MAX_PORTS,
24 };
25 
26 const SOCKET_TIMEOUT_MS: u64 = 2000;
27 
28 /// Host backend device provider is a xhci backend device provider that would provide pass through
29 /// devices.
30 pub enum HostBackendDeviceProvider {
31     // The provider is created but not yet started.
32     Created {
33         sock: MsgSocket<UsbControlResult, UsbControlCommand>,
34     },
35     // The provider is started on an event loop.
36     Started {
37         inner: Arc<ProviderInner>,
38     },
39     // The provider has failed.
40     Failed,
41 }
42 
43 impl HostBackendDeviceProvider {
new() -> Result<(UsbControlSocket, HostBackendDeviceProvider)>44     pub fn new() -> Result<(UsbControlSocket, HostBackendDeviceProvider)> {
45         let (child_sock, control_sock) = UnixSeqpacket::pair().map_err(Error::CreateControlSock)?;
46         control_sock
47             .set_write_timeout(Some(Duration::from_millis(SOCKET_TIMEOUT_MS)))
48             .map_err(Error::SetupControlSock)?;
49         control_sock
50             .set_read_timeout(Some(Duration::from_millis(SOCKET_TIMEOUT_MS)))
51             .map_err(Error::SetupControlSock)?;
52 
53         let provider = HostBackendDeviceProvider::Created {
54             sock: MsgSocket::new(child_sock),
55         };
56         Ok((MsgSocket::new(control_sock), provider))
57     }
58 
start_helper( &mut self, fail_handle: Arc<dyn FailHandle>, event_loop: Arc<EventLoop>, hub: Arc<UsbHub>, ) -> Result<()>59     fn start_helper(
60         &mut self,
61         fail_handle: Arc<dyn FailHandle>,
62         event_loop: Arc<EventLoop>,
63         hub: Arc<UsbHub>,
64     ) -> Result<()> {
65         match mem::replace(self, HostBackendDeviceProvider::Failed) {
66             HostBackendDeviceProvider::Created { sock } => {
67                 let ctx = Context::new(event_loop.clone())?;
68                 let hotplug_handler = HotplugHandler::new(hub.clone());
69                 ctx.set_hotplug_handler(hotplug_handler);
70                 let job_queue =
71                     AsyncJobQueue::init(&event_loop).map_err(Error::StartAsyncJobQueue)?;
72                 let inner = Arc::new(ProviderInner::new(fail_handle, job_queue, ctx, sock, hub));
73                 let handler: Arc<dyn EventHandler> = inner.clone();
74                 event_loop
75                     .add_event(
76                         &inner.sock,
77                         WatchingEvents::empty().set_read(),
78                         Arc::downgrade(&handler),
79                     )
80                     .map_err(Error::AddToEventLoop)?;
81                 *self = HostBackendDeviceProvider::Started { inner };
82                 Ok(())
83             }
84             HostBackendDeviceProvider::Started { .. } => {
85                 error!("Host backend provider has already started");
86                 Err(Error::BadBackendProviderState)
87             }
88             HostBackendDeviceProvider::Failed => {
89                 error!("Host backend provider has already failed");
90                 Err(Error::BadBackendProviderState)
91             }
92         }
93     }
94 }
95 
96 impl XhciBackendDeviceProvider for HostBackendDeviceProvider {
start( &mut self, fail_handle: Arc<dyn FailHandle>, event_loop: Arc<EventLoop>, hub: Arc<UsbHub>, ) -> std::result::Result<(), ()>97     fn start(
98         &mut self,
99         fail_handle: Arc<dyn FailHandle>,
100         event_loop: Arc<EventLoop>,
101         hub: Arc<UsbHub>,
102     ) -> std::result::Result<(), ()> {
103         self.start_helper(fail_handle, event_loop, hub)
104             .map_err(|e| {
105                 error!("failed to start host backend device provider: {}", e);
106             })
107     }
108 
keep_fds(&self) -> Vec<RawFd>109     fn keep_fds(&self) -> Vec<RawFd> {
110         match self {
111             HostBackendDeviceProvider::Created { sock } => vec![sock.as_raw_fd()],
112             _ => {
113                 error!(
114                     "Trying to get keepfds when HostBackendDeviceProvider is not in created state"
115                 );
116                 vec![]
117             }
118         }
119     }
120 }
121 
122 /// ProviderInner listens to control socket.
123 pub struct ProviderInner {
124     fail_handle: Arc<dyn FailHandle>,
125     job_queue: Arc<AsyncJobQueue>,
126     ctx: Context,
127     sock: MsgSocket<UsbControlResult, UsbControlCommand>,
128     usb_hub: Arc<UsbHub>,
129 }
130 
131 impl ProviderInner {
new( fail_handle: Arc<dyn FailHandle>, job_queue: Arc<AsyncJobQueue>, ctx: Context, sock: MsgSocket<UsbControlResult, UsbControlCommand>, usb_hub: Arc<UsbHub>, ) -> ProviderInner132     fn new(
133         fail_handle: Arc<dyn FailHandle>,
134         job_queue: Arc<AsyncJobQueue>,
135         ctx: Context,
136         sock: MsgSocket<UsbControlResult, UsbControlCommand>,
137         usb_hub: Arc<UsbHub>,
138     ) -> ProviderInner {
139         ProviderInner {
140             fail_handle,
141             job_queue,
142             ctx,
143             sock,
144             usb_hub,
145         }
146     }
147 
handle_list_devices(&self, ports: [u8; USB_CONTROL_MAX_PORTS]) -> UsbControlResult148     fn handle_list_devices(&self, ports: [u8; USB_CONTROL_MAX_PORTS]) -> UsbControlResult {
149         let mut devices: [UsbControlAttachedDevice; USB_CONTROL_MAX_PORTS] = Default::default();
150         for (result_index, &port_id) in ports.iter().enumerate() {
151             match self.usb_hub.get_port(port_id).and_then(|p| {
152                 p.get_backend_device()
153                     .as_ref()
154                     .map(|d| (d.get_vid(), d.get_pid()))
155             }) {
156                 Some((vendor_id, product_id)) => {
157                     devices[result_index] = UsbControlAttachedDevice {
158                         port: port_id,
159                         vendor_id,
160                         product_id,
161                     }
162                 }
163                 None => continue,
164             }
165         }
166         UsbControlResult::Devices(devices)
167     }
168 
on_event_helper(&self) -> Result<()>169     fn on_event_helper(&self) -> Result<()> {
170         let cmd = self.sock.recv().map_err(Error::ReadControlSock)?;
171         match cmd {
172             UsbControlCommand::AttachDevice {
173                 bus,
174                 addr,
175                 vid,
176                 pid,
177                 fd: usb_fd,
178             } => {
179                 let _ = usb_fd;
180                 #[cfg(not(feature = "sandboxed-libusb"))]
181                 let device = match self.ctx.get_device(bus, addr, vid, pid) {
182                     Some(d) => d,
183                     None => {
184                         error!(
185                             "cannot get device bus: {}, addr: {}, vid: {}, pid: {}",
186                             bus, addr, vid, pid
187                         );
188                         // The send failure will be logged, but event loop still think the event is
189                         // handled.
190                         let _ = self
191                             .sock
192                             .send(&UsbControlResult::NoSuchDevice)
193                             .map_err(Error::WriteControlSock)?;
194                         return Ok(());
195                     }
196                 };
197                 #[cfg(feature = "sandboxed-libusb")]
198                 let (device, device_handle) = {
199                     use vm_control::MaybeOwnedFd;
200 
201                     let usb_file = match usb_fd {
202                         Some(MaybeOwnedFd::Owned(file)) => file,
203                         _ => {
204                             let _ = self
205                                 .sock
206                                 .send(&UsbControlResult::FailedToOpenDevice)
207                                 .map_err(Error::WriteControlSock);
208                             return Ok(());
209                         }
210                     };
211 
212                     let device_fd = usb_file.as_raw_fd();
213 
214                     let device = match self.ctx.get_device(usb_file) {
215                         Some(d) => d,
216                         None => {
217                             error!(
218                                 "cannot get device bus: {}, addr: {}, vid: {}, pid: {}",
219                                 bus, addr, vid, pid
220                             );
221                             // The send failure will be logged, but event loop still think the event
222                             // is handled.
223                             let _ = self
224                                 .sock
225                                 .send(&UsbControlResult::NoSuchDevice)
226                                 .map_err(Error::WriteControlSock);
227                             return Ok(());
228                         }
229                     };
230 
231                     let device_handle = {
232                         // This is safe only when fd is an fd of the current device.
233                         match unsafe { device.open_fd(device_fd) } {
234                             Ok(handle) => handle,
235                             Err(e) => {
236                                 error!("fail to open device: {:?}", e);
237                                 // The send failure will be logged, but event loop still think
238                                 // the event is handled.
239                                 let _ = self
240                                     .sock
241                                     .send(&UsbControlResult::FailedToOpenDevice)
242                                     .map_err(Error::WriteControlSock);
243                                 return Ok(());
244                             }
245                         }
246                     };
247 
248                     // Resetting the device is used to make sure it is in a known state, but it may
249                     // still function if the reset fails.
250                     if let Err(e) = device_handle.reset() {
251                         error!("failed to reset device after attach: {:?}", e);
252                     }
253                     (device, device_handle)
254                 };
255 
256                 #[cfg(not(feature = "sandboxed-libusb"))]
257                 let device_handle = match device.open() {
258                     Ok(handle) => handle,
259                     Err(e) => {
260                         error!("fail to open device: {:?}", e);
261                         // The send failure will be logged, but event loop still think the event is
262                         // handled.
263                         let _ = self
264                             .sock
265                             .send(&UsbControlResult::FailedToOpenDevice)
266                             .map_err(Error::WriteControlSock);
267                         return Ok(());
268                     }
269                 };
270                 let device = Box::new(HostDevice::new(
271                     self.fail_handle.clone(),
272                     self.job_queue.clone(),
273                     device,
274                     device_handle,
275                 ));
276                 let port = self.usb_hub.connect_backend(device);
277                 match port {
278                     Ok(port) => {
279                         // The send failure will be logged, but event loop still think the event is
280                         // handled.
281                         let _ = self
282                             .sock
283                             .send(&UsbControlResult::Ok { port })
284                             .map_err(Error::WriteControlSock);
285                     }
286                     Err(e) => {
287                         error!("failed to connect device to hub: {}", e);
288                         // The send failure will be logged, but event loop still think the event is
289                         // handled.
290                         let _ = self
291                             .sock
292                             .send(&UsbControlResult::NoAvailablePort)
293                             .map_err(Error::WriteControlSock);
294                     }
295                 }
296                 Ok(())
297             }
298             UsbControlCommand::DetachDevice { port } => {
299                 match self.usb_hub.disconnect_port(port) {
300                     Ok(()) => {
301                         // The send failure will be logged, but event loop still think the event is
302                         // handled.
303                         let _ = self
304                             .sock
305                             .send(&UsbControlResult::Ok { port })
306                             .map_err(Error::WriteControlSock);
307                     }
308                     Err(e) => {
309                         error!("failed to disconnect device from port {}: {}", port, e);
310                         // The send failure will be logged, but event loop still think the event is
311                         // handled.
312                         let _ = self
313                             .sock
314                             .send(&UsbControlResult::NoSuchDevice)
315                             .map_err(Error::WriteControlSock);
316                     }
317                 }
318                 Ok(())
319             }
320             UsbControlCommand::ListDevice { ports } => {
321                 let result = self.handle_list_devices(ports);
322                 // The send failure will be logged, but event loop still think the event is
323                 // handled.
324                 let _ = self.sock.send(&result).map_err(Error::WriteControlSock);
325                 Ok(())
326             }
327         }
328     }
329 }
330 
331 impl EventHandler for ProviderInner {
on_event(&self) -> std::result::Result<(), ()>332     fn on_event(&self) -> std::result::Result<(), ()> {
333         self.on_event_helper().map_err(|e| {
334             error!("host backend device provider failed: {}", e);
335         })
336     }
337 }
338