summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-03-25 13:54:50 -0700
committerCommit Bot <commit-bot@chromium.org>2020-04-23 07:17:58 +0000
commitb865810340f1b264b407137c4e69ad232194cc5e (patch)
tree49bb7d6e14d315a21fdd5c8e1365ddfebf3e5b80
parente538d5216fe1ec0f9755e1550cd7e67304653982 (diff)
downloadcrosvm-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.rs10
-rw-r--r--devices/src/lib.rs2
-rw-r--r--devices/src/serial.rs46
-rw-r--r--devices/src/serial_device.rs19
-rw-r--r--devices/src/virtio/console.rs23
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 {