diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2020-03-25 13:54:50 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-23 07:17:58 +0000 |
commit | b865810340f1b264b407137c4e69ad232194cc5e (patch) | |
tree | 49bb7d6e14d315a21fdd5c8e1365ddfebf3e5b80 | |
parent | e538d5216fe1ec0f9755e1550cd7e67304653982 (diff) | |
download | crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar.gz crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar.bz2 crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar.lz crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar.xz crosvm-b865810340f1b264b407137c4e69ad232194cc5e.tar.zst crosvm-b865810340f1b264b407137c4e69ad232194cc5e.zip |
devices: add SerialDevice trait
This will be used to allow generic code to create serial devices as well as virtio-console devices. Also remove the new_in_out, new_out, and new_sink constructors for Serial and Console, since they are not used anywhere. BUG=chromium:1059924 TEST=cargo build Change-Id: I76da343e347aed36dabd3aa0541acf24c64fe122 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2127321 Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
-rw-r--r-- | arch/src/serial.rs | 10 | ||||
-rw-r--r-- | devices/src/lib.rs | 2 | ||||
-rw-r--r-- | devices/src/serial.rs | 46 | ||||
-rw-r--r-- | devices/src/serial_device.rs | 19 | ||||
-rw-r--r-- | devices/src/virtio/console.rs | 23 |
5 files changed, 48 insertions, 52 deletions
diff --git a/arch/src/serial.rs b/arch/src/serial.rs index c0e27dc..3892c64 100644 --- a/arch/src/serial.rs +++ b/arch/src/serial.rs @@ -11,7 +11,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; -use devices::{Bus, ProxyDevice, Serial}; +use devices::{Bus, ProxyDevice, Serial, SerialDevice}; use io_jail::Minijail; use sync::Mutex; use sys_util::{read_raw_stdin, syslog, EventFd}; @@ -97,11 +97,11 @@ impl SerialParameters { /// * `evt_fd` - eventfd used for interrupt events /// * `keep_fds` - Vector of FDs required by this device if it were sandboxed in a child /// process. `evt_fd` will always be added to this vector by this function. - pub fn create_serial_device( + pub fn create_serial_device<T: SerialDevice>( &self, evt_fd: &EventFd, keep_fds: &mut Vec<RawFd>, - ) -> std::result::Result<Serial, Error> { + ) -> std::result::Result<T, Error> { let evt_fd = evt_fd.try_clone().map_err(Error::CloneEventFd)?; keep_fds.push(evt_fd.as_raw_fd()); let input: Option<Box<dyn io::Read + Send>> = if let Some(input_path) = &self.input { @@ -145,7 +145,7 @@ impl SerialParameters { }, SerialType::UnixSocket => return Err(Error::Unimplemented(SerialType::UnixSocket)), }; - Ok(Serial::new(evt_fd, input, output)) + Ok(T::new(evt_fd, input, output, keep_fds.to_vec())) } } @@ -240,7 +240,7 @@ pub fn add_serial_devices( let mut preserved_fds = Vec::new(); let com = param - .create_serial_device(&com_evt, &mut preserved_fds) + .create_serial_device::<Serial>(&com_evt, &mut preserved_fds) .map_err(DeviceRegistrationError::CreateSerialDevice)?; match serial_jail.as_ref() { diff --git a/devices/src/lib.rs b/devices/src/lib.rs index 75c27a8..be2bf9c 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -17,6 +17,7 @@ mod proxy; mod register_space; pub mod acpi; mod serial; +mod serial_device; pub mod split_irqchip_common; pub mod usb; mod utils; @@ -39,6 +40,7 @@ pub use self::pl030::Pl030; pub use self::proxy::Error as ProxyError; pub use self::proxy::ProxyDevice; pub use self::serial::Serial; +pub use self::serial_device::SerialDevice; pub use self::usb::host_backend::host_backend_device_provider::HostBackendDeviceProvider; pub use self::usb::xhci::xhci_controller::XhciController; pub use self::vfio::{VfioContainer, VfioDevice}; diff --git a/devices/src/serial.rs b/devices/src/serial.rs index 756217d..2af988e 100644 --- a/devices/src/serial.rs +++ b/devices/src/serial.rs @@ -4,6 +4,7 @@ use std::collections::VecDeque; use std::io::{self, Write}; +use std::os::unix::io::RawFd; use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::mpsc::{channel, Receiver, TryRecvError}; use std::sync::Arc; @@ -11,7 +12,7 @@ use std::thread::{self}; use sys_util::{error, EventFd, Result}; -use crate::BusDevice; +use crate::{BusDevice, SerialDevice}; const LOOP_SIZE: usize = 0x40; @@ -81,11 +82,12 @@ pub struct Serial { out: Option<Box<dyn io::Write + Send>>, } -impl Serial { - pub fn new( +impl SerialDevice for Serial { + fn new( interrupt_evt: EventFd, input: Option<Box<dyn io::Read + Send>>, out: Option<Box<dyn io::Write + Send>>, + _keep_fds: Vec<RawFd>, ) -> Serial { Serial { interrupt_enable: Default::default(), @@ -103,28 +105,9 @@ impl Serial { out, } } +} - /// Constructs a Serial port ready for input and output. - /// - /// The stream `input` should not block, instead returning 0 bytes if are no bytes available. - pub fn new_in_out( - interrupt_evt: EventFd, - input: Box<dyn io::Read + Send>, - out: Box<dyn io::Write + Send>, - ) -> Serial { - Self::new(interrupt_evt, Some(input), Some(out)) - } - - /// Constructs a Serial port ready for output but not input. - pub fn new_out(interrupt_evt: EventFd, out: Box<dyn io::Write + Send>) -> Serial { - Self::new(interrupt_evt, None, Some(out)) - } - - /// Constructs a Serial port with no connected input or output. - pub fn new_sink(interrupt_evt: EventFd) -> Serial { - Self::new(interrupt_evt, None, None) - } - +impl Serial { /// Queues raw bytes for the guest to read and signals the interrupt if the line status would /// change. These bytes will be read by the guest before any bytes from the input stream that /// have not already been queued. @@ -425,7 +408,12 @@ mod tests { let intr_evt = EventFd::new().unwrap(); let serial_out = SharedBuffer::new(); - let mut serial = Serial::new_out(intr_evt, Box::new(serial_out.clone())); + let mut serial = Serial::new( + intr_evt, + None, + Some(Box::new(serial_out.clone())), + Vec::new(), + ); serial.write(DATA as u64, &['a' as u8]); serial.write(DATA as u64, &['b' as u8]); @@ -441,8 +429,12 @@ mod tests { let intr_evt = EventFd::new().unwrap(); let serial_out = SharedBuffer::new(); - let mut serial = - Serial::new_out(intr_evt.try_clone().unwrap(), Box::new(serial_out.clone())); + let mut serial = Serial::new( + intr_evt.try_clone().unwrap(), + None, + Some(Box::new(serial_out.clone())), + Vec::new(), + ); serial.write(IER as u64, &[IER_RECV_BIT]); serial diff --git a/devices/src/serial_device.rs b/devices/src/serial_device.rs new file mode 100644 index 0000000..9377556 --- /dev/null +++ b/devices/src/serial_device.rs @@ -0,0 +1,19 @@ +// Copyright 2020 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std::io; +use std::os::unix::io::RawFd; + +use sys_util::EventFd; + +/// Abstraction over serial-like devices that can be created given an event and optional input and +/// output streams. +pub trait SerialDevice { + fn new( + interrupt_evt: EventFd, + input: Option<Box<dyn io::Read + Send>>, + output: Option<Box<dyn io::Write + Send>>, + keep_fds: Vec<RawFd>, + ) -> Self; +} diff --git a/devices/src/virtio/console.rs b/devices/src/virtio/console.rs index 38f5bf1..50a5a76 100644 --- a/devices/src/virtio/console.rs +++ b/devices/src/virtio/console.rs @@ -13,6 +13,7 @@ use sys_util::{error, EventFd, GuestMemory, PollContext, PollToken}; use super::{ copy_config, Interrupt, Queue, Reader, VirtioDevice, Writer, TYPE_CONSOLE, VIRTIO_F_VERSION_1, }; +use crate::SerialDevice; const QUEUE_SIZE: u16 = 256; @@ -303,8 +304,9 @@ pub struct Console { keep_fds: Vec<RawFd>, } -impl Console { +impl SerialDevice for Console { fn new( + _evt_fd: EventFd, input: Option<Box<dyn io::Read + Send>>, output: Option<Box<dyn io::Write + Send>>, keep_fds: Vec<RawFd>, @@ -317,25 +319,6 @@ impl Console { keep_fds, } } - - /// Constructs a console with input and output streams. - pub fn new_in_out( - input: Box<dyn io::Read + Send>, - out: Box<dyn io::Write + Send>, - keep_fds: Vec<RawFd>, - ) -> Console { - Self::new(Some(input), Some(out), keep_fds) - } - - /// Constructs a console with an output stream but no input. - pub fn new_out(out: Box<dyn io::Write + Send>, keep_fds: Vec<RawFd>) -> Console { - Self::new(None, Some(out), keep_fds) - } - - /// Constructs a console with no connected input or output. - pub fn new_sink() -> Console { - Self::new(None, None, Vec::new()) - } } impl Drop for Console { |