summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-02-14 16:46:36 -0800
committerCommit Bot <commit-bot@chromium.org>2020-04-23 07:17:55 +0000
commitfbd6122f0b722f40bb14f0c3a26342fa46d5a89d (patch)
tree237d82fabe09b84b02ed2b05963ab698a8eaf31e /devices
parent2c1417b43a1846d21bc589563460de4b962afcc6 (diff)
downloadcrosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar.gz
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar.bz2
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar.lz
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar.xz
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.tar.zst
crosvm-fbd6122f0b722f40bb14f0c3a26342fa46d5a89d.zip
arch, devices: move serial creation to arch
Split the serial code  into two parts:

- Configuration and setup: arch/src/serial.rs
- Serial device emulation: devices/src/serial.rs

No change in functionality - this is just preparation for generalizing
the command line parsing/setup code so that it can be used with virtio
console devices as well.

BUG=chromium:1059924
TEST=emerge-nami crosvm
TEST=emerge-kevin crosvm

Change-Id: I0aaf9dd6f8096eac4a17077ab5bf569f57d64ff5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2127319
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/lib.rs5
-rw-r--r--devices/src/serial.rs201
2 files changed, 4 insertions, 202 deletions
diff --git a/devices/src/lib.rs b/devices/src/lib.rs
index 9ed8417..75c27a8 100644
--- a/devices/src/lib.rs
+++ b/devices/src/lib.rs
@@ -38,10 +38,7 @@ pub use self::pit::{Pit, PitError};
 pub use self::pl030::Pl030;
 pub use self::proxy::Error as ProxyError;
 pub use self::proxy::ProxyDevice;
-pub use self::serial::Error as SerialError;
-pub use self::serial::{
-    get_serial_tty_string, Serial, SerialParameters, SerialType, DEFAULT_SERIAL_PARAMS, SERIAL_ADDR,
-};
+pub use self::serial::Serial;
 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 caf1ee0..756217d 100644
--- a/devices/src/serial.rs
+++ b/devices/src/serial.rs
@@ -3,18 +3,13 @@
 // found in the LICENSE file.
 
 use std::collections::VecDeque;
-use std::fmt::{self, Display};
-use std::fs::File;
-use std::io::{self, stdin, stdout, Read, Write};
-use std::os::unix::io::{AsRawFd, RawFd};
-use std::path::PathBuf;
-use std::str::FromStr;
+use std::io::{self, Write};
 use std::sync::atomic::{AtomicU8, Ordering};
 use std::sync::mpsc::{channel, Receiver, TryRecvError};
 use std::sync::Arc;
 use std::thread::{self};
 
-use sys_util::{error, read_raw_stdin, syslog, EventFd, Result};
+use sys_util::{error, EventFd, Result};
 
 use crate::BusDevice;
 
@@ -62,196 +57,6 @@ const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT;
 const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT;
 const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps
 
-#[derive(Debug)]
-pub enum Error {
-    CloneEventFd(sys_util::Error),
-    InvalidSerialType(String),
-    PathRequired,
-    FileError(std::io::Error),
-    Unimplemented(SerialType),
-}
-
-impl Display for Error {
-    #[remain::check]
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        use self::Error::*;
-
-        #[sorted]
-        match self {
-            CloneEventFd(e) => write!(f, "unable to clone an EventFd: {}", e),
-            FileError(e) => write!(f, "Unable to open/create file: {}", e),
-            InvalidSerialType(e) => write!(f, "invalid serial type: {}", e),
-            PathRequired => write!(f, "serial device type file requires a path"),
-            Unimplemented(e) => write!(f, "serial device type {} not implemented", e.to_string()),
-        }
-    }
-}
-
-/// Enum for possible type of serial devices
-#[derive(Debug)]
-pub enum SerialType {
-    File,
-    Stdout,
-    Sink,
-    Syslog,
-    UnixSocket, // NOT IMPLEMENTED
-}
-
-impl Display for SerialType {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let s = match &self {
-            SerialType::File => "File".to_string(),
-            SerialType::Stdout => "Stdout".to_string(),
-            SerialType::Sink => "Sink".to_string(),
-            SerialType::Syslog => "Syslog".to_string(),
-            SerialType::UnixSocket => "UnixSocket".to_string(),
-        };
-
-        write!(f, "{}", s)
-    }
-}
-
-impl FromStr for SerialType {
-    type Err = Error;
-    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
-        match s {
-            "file" | "File" => Ok(SerialType::File),
-            "stdout" | "Stdout" => Ok(SerialType::Stdout),
-            "sink" | "Sink" => Ok(SerialType::Sink),
-            "syslog" | "Syslog" => Ok(SerialType::Syslog),
-            "unix" | "UnixSocket" => Ok(SerialType::UnixSocket),
-            _ => Err(Error::InvalidSerialType(s.to_string())),
-        }
-    }
-}
-
-/// Holds the parameters for a serial device
-#[derive(Debug)]
-pub struct SerialParameters {
-    pub type_: SerialType,
-    pub path: Option<PathBuf>,
-    pub input: Option<PathBuf>,
-    pub num: u8,
-    pub console: bool,
-    pub stdin: bool,
-}
-
-impl SerialParameters {
-    /// Helper function to create a serial device from the defined parameters.
-    ///
-    /// # Arguments
-    /// * `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(
-        &self,
-        evt_fd: &EventFd,
-        keep_fds: &mut Vec<RawFd>,
-    ) -> std::result::Result<Serial, 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 {
-            let input_file = File::open(input_path.as_path()).map_err(Error::FileError)?;
-            keep_fds.push(input_file.as_raw_fd());
-            Some(Box::new(input_file))
-        } else if self.stdin {
-            keep_fds.push(stdin().as_raw_fd());
-            // This wrapper is used in place of the libstd native version because we don't want
-            // buffering for stdin.
-            struct StdinWrapper;
-            impl io::Read for StdinWrapper {
-                fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
-                    read_raw_stdin(out).map_err(|e| e.into())
-                }
-            }
-            Some(Box::new(StdinWrapper))
-        } else {
-            None
-        };
-        match self.type_ {
-            SerialType::Stdout => {
-                keep_fds.push(stdout().as_raw_fd());
-                Ok(Serial::new(evt_fd, input, Some(Box::new(stdout()))))
-            }
-            SerialType::Sink => Ok(Serial::new(evt_fd, input, None)),
-            SerialType::Syslog => {
-                syslog::push_fds(keep_fds);
-                Ok(Serial::new(
-                    evt_fd,
-                    input,
-                    Some(Box::new(syslog::Syslogger::new(
-                        syslog::Priority::Info,
-                        syslog::Facility::Daemon,
-                    ))),
-                ))
-            }
-            SerialType::File => match &self.path {
-                Some(path) => {
-                    let file = File::create(path.as_path()).map_err(Error::FileError)?;
-                    keep_fds.push(file.as_raw_fd());
-                    Ok(Serial::new(evt_fd, input, Some(Box::new(file))))
-                }
-                _ => Err(Error::PathRequired),
-            },
-            SerialType::UnixSocket => Err(Error::Unimplemented(SerialType::UnixSocket)),
-        }
-    }
-}
-
-// Structure for holding the default configuration of the serial devices.
-pub const DEFAULT_SERIAL_PARAMS: [SerialParameters; 4] = [
-    SerialParameters {
-        type_: SerialType::Stdout,
-        path: None,
-        input: None,
-        num: 1,
-        console: true,
-        stdin: true,
-    },
-    SerialParameters {
-        type_: SerialType::Sink,
-        path: None,
-        input: None,
-        num: 2,
-        console: false,
-        stdin: false,
-    },
-    SerialParameters {
-        type_: SerialType::Sink,
-        path: None,
-        input: None,
-        num: 3,
-        console: false,
-        stdin: false,
-    },
-    SerialParameters {
-        type_: SerialType::Sink,
-        path: None,
-        input: None,
-        num: 4,
-        console: false,
-        stdin: false,
-    },
-];
-
-/// Address for Serial ports in x86
-pub const SERIAL_ADDR: [u64; 4] = [0x3f8, 0x2f8, 0x3e8, 0x2e8];
-
-/// String representations of serial devices
-pub const SERIAL_TTY_STRINGS: [&str; 4] = ["ttyS0", "ttyS1", "ttyS2", "ttyS3"];
-
-/// Helper function to get the tty string of a serial device based on the port number. Will default
-///  to ttyS0 if an invalid number is given.
-pub fn get_serial_tty_string(stdio_serial_num: u8) -> String {
-    match stdio_serial_num {
-        1 => SERIAL_TTY_STRINGS[0].to_string(),
-        2 => SERIAL_TTY_STRINGS[1].to_string(),
-        3 => SERIAL_TTY_STRINGS[2].to_string(),
-        4 => SERIAL_TTY_STRINGS[3].to_string(),
-        _ => SERIAL_TTY_STRINGS[0].to_string(),
-    }
-}
-
 /// Emulates serial COM ports commonly seen on x86 I/O ports 0x3f8/0x2f8/0x3e8/0x2e8.
 ///
 /// This can optionally write the guest's output to a Write trait object. To send input to the
@@ -277,7 +82,7 @@ pub struct Serial {
 }
 
 impl Serial {
-    fn new(
+    pub fn new(
         interrupt_evt: EventFd,
         input: Option<Box<dyn io::Read + Send>>,
         out: Option<Box<dyn io::Write + Send>>,