summary refs log tree commit diff
path: root/src/main.rs
diff options
context:
space:
mode:
authorJorge E. Moreira <jemoreira@google.com>2019-08-01 14:40:03 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-03 20:03:23 +0000
commit1e26230f3a490a7955d2ea9fe7855af5498ced70 (patch)
treede59ab5928eac607c33bd4de6289bb230f2f6c51 /src/main.rs
parent54e660ba8b912cf9c1fe7837cd42d21b9cfe9133 (diff)
downloadcrosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar.gz
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar.bz2
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar.lz
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar.xz
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.tar.zst
crosvm-1e26230f3a490a7955d2ea9fe7855af5498ced70.zip
Allow to connect standard input to a serial port other than the guest console
Before this change, setting console=true on a serial port caused that
port to be the one connected to the crosvm process' standard input. By
adding an extra 'stdin' argument to the serial parameters it's
possible to make those concepts independent.
Just as with the console argument, stdin defaults to serial port
1 (ttyS0) when not provided and it's possible to set no serial port
connected to stdin (or set as the console) by defining the first
serial port without the stdin (console) argument.

BUG=b/138616941
TEST=boot debian guest in debian host, boot cuttlefish in debian host
Change-Id: I7273e6860218521073df93a4ad71e31c7da522a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1731139
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Auto-Submit: Jorge Moreira Broche <jemoreira@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index 81f20a7..78dfbf2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -251,6 +251,7 @@ fn parse_serial_options(s: &str) -> argument::Result<SerialParameters> {
         path: None,
         num: 1,
         console: false,
+        stdin: false,
     };
 
     let opts = s
@@ -285,6 +286,11 @@ fn parse_serial_options(s: &str) -> argument::Result<SerialParameters> {
                     ))
                 })?
             }
+            "stdin" => {
+                serial_setting.stdin = v.parse::<bool>().map_err(|e| {
+                    argument::Error::Syntax(format!("serial device stdin is not parseable: {}", e))
+                })?
+            }
             "path" => serial_setting.path = Some(PathBuf::from(v)),
             _ => {
                 return Err(argument::Error::UnknownArgument(format!(
@@ -409,6 +415,15 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
                 }
             }
 
+            if serial_params.stdin {
+                if let Some(previous_stdin) = cfg.serial_parameters.values().find(|sp| sp.stdin) {
+                    return Err(argument::Error::TooManyArguments(format!(
+                        "serial device {} already connected to standard input",
+                        previous_stdin.num
+                    )));
+                }
+            }
+
             cfg.serial_parameters.insert(num, serial_params);
         }
         "syslog-tag" => {
@@ -840,13 +855,14 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
           Argument::flag("cras-capture", "Enable capturing audio from CRAS server to the cras-audio device"),
           Argument::flag("null-audio", "Add an audio device to the VM that plays samples to /dev/null"),
           Argument::value("serial",
-                          "type=TYPE,[num=NUM,path=PATH,console]",
+                          "type=TYPE,[num=NUM,path=PATH,console,stdin]",
                           "Comma seperated key=value pairs for setting up serial devices. Can be given more than once.
                           Possible key values:
                           type=(stdout,syslog,sink,file) - Where to route the serial device
                           num=(1,2,3,4) - Serial Device Number. If not provided, num will default to 1.
                           path=PATH - The path to the file to write to when type=file
                           console - Use this serial device as the guest console. Can only be given once. Will default to first serial port if not provided.
+                          stdin - Direct standard input to this serial device. Can only be given once. Will default to first serial port if not provided.
                           "),
           Argument::value("syslog-tag", "TAG", "When logging to syslog, use the provided tag."),
           Argument::value("wayland-sock", "PATH", "Path to the Wayland socket to use."),
@@ -1423,7 +1439,8 @@ mod tests {
 
     #[test]
     fn parse_serial_vaild() {
-        parse_serial_options("type=syslog,num=1,console=true").expect("parse should have succeded");
+        parse_serial_options("type=syslog,num=1,console=true,stdin=true")
+            .expect("parse should have succeded");
     }
 
     #[test]
@@ -1455,4 +1472,13 @@ mod tests {
     fn parse_serial_invalid_option() {
         parse_serial_options("type=syslog,speed=lightspeed").expect_err("parse should have failed");
     }
+
+    #[test]
+    fn parse_serial_invalid_two_stdin() {
+        let mut config = Config::default();
+        set_argument(&mut config, "serial", Some("num=1,type=stdout,stdin=true"))
+            .expect("should parse the first serial argument");
+        set_argument(&mut config, "serial", Some("num=2,type=stdout,stdin=true"))
+            .expect_err("should fail to parse a second serial port connected to stdin");
+    }
 }