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